Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
michael@0 | 2 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef MOZILLA_LAYERS_EFFECTS_H |
michael@0 | 7 | #define MOZILLA_LAYERS_EFFECTS_H |
michael@0 | 8 | |
michael@0 | 9 | #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc |
michael@0 | 10 | #include "mozilla/RefPtr.h" // for RefPtr, TemporaryRef, etc |
michael@0 | 11 | #include "mozilla/gfx/Matrix.h" // for Matrix4x4 |
michael@0 | 12 | #include "mozilla/gfx/Point.h" // for IntSize |
michael@0 | 13 | #include "mozilla/gfx/Rect.h" // for Rect |
michael@0 | 14 | #include "mozilla/gfx/Types.h" // for Filter, etc |
michael@0 | 15 | #include "mozilla/layers/CompositorTypes.h" // for EffectTypes, etc |
michael@0 | 16 | #include "mozilla/layers/LayersTypes.h" |
michael@0 | 17 | #include "mozilla/layers/TextureHost.h" // for CompositingRenderTarget, etc |
michael@0 | 18 | #include "mozilla/mozalloc.h" // for operator delete, etc |
michael@0 | 19 | #include "nscore.h" // for nsACString |
michael@0 | 20 | |
michael@0 | 21 | namespace mozilla { |
michael@0 | 22 | namespace layers { |
michael@0 | 23 | |
michael@0 | 24 | /** |
michael@0 | 25 | * Effects and effect chains are used by the compositor API (see Compositor.h). |
michael@0 | 26 | * An effect chain represents a rendering method, for example some shader and |
michael@0 | 27 | * the data required for that shader to run. An effect is some component of the |
michael@0 | 28 | * chain and its data. |
michael@0 | 29 | * |
michael@0 | 30 | * An effect chain consists of a primary effect - how the 'texture' memory should |
michael@0 | 31 | * be interpreted (RGBA, BGRX, YCBCR, etc.) - and any number of secondary effects |
michael@0 | 32 | * - any way in which rendering can be changed, e.g., applying a mask layer. |
michael@0 | 33 | * |
michael@0 | 34 | * During the rendering process, an effect chain is created by the layer being |
michael@0 | 35 | * rendered and the primary effect is added by the compositable host. Secondary |
michael@0 | 36 | * effects may be added by the layer or compositable. The effect chain is passed |
michael@0 | 37 | * to the compositor by the compositable host as a parameter to DrawQuad. |
michael@0 | 38 | */ |
michael@0 | 39 | |
michael@0 | 40 | struct Effect |
michael@0 | 41 | { |
michael@0 | 42 | NS_INLINE_DECL_REFCOUNTING(Effect) |
michael@0 | 43 | |
michael@0 | 44 | Effect(EffectTypes aType) : mType(aType) {} |
michael@0 | 45 | |
michael@0 | 46 | EffectTypes mType; |
michael@0 | 47 | |
michael@0 | 48 | virtual void PrintInfo(nsACString& aTo, const char* aPrefix) = 0; |
michael@0 | 49 | |
michael@0 | 50 | protected: |
michael@0 | 51 | virtual ~Effect() {} |
michael@0 | 52 | }; |
michael@0 | 53 | |
michael@0 | 54 | // Render from a texture |
michael@0 | 55 | struct TexturedEffect : public Effect |
michael@0 | 56 | { |
michael@0 | 57 | TexturedEffect(EffectTypes aType, |
michael@0 | 58 | TextureSource *aTexture, |
michael@0 | 59 | bool aPremultiplied, |
michael@0 | 60 | gfx::Filter aFilter) |
michael@0 | 61 | : Effect(aType) |
michael@0 | 62 | , mTextureCoords(0, 0, 1.0f, 1.0f) |
michael@0 | 63 | , mTexture(aTexture) |
michael@0 | 64 | , mPremultiplied(aPremultiplied) |
michael@0 | 65 | , mFilter(aFilter) |
michael@0 | 66 | {} |
michael@0 | 67 | |
michael@0 | 68 | virtual const char* Name() = 0; |
michael@0 | 69 | virtual void PrintInfo(nsACString& aTo, const char* aPrefix); |
michael@0 | 70 | |
michael@0 | 71 | gfx::Rect mTextureCoords; |
michael@0 | 72 | TextureSource* mTexture; |
michael@0 | 73 | bool mPremultiplied; |
michael@0 | 74 | gfx::Filter mFilter;; |
michael@0 | 75 | }; |
michael@0 | 76 | |
michael@0 | 77 | // Support an alpha mask. |
michael@0 | 78 | struct EffectMask : public Effect |
michael@0 | 79 | { |
michael@0 | 80 | EffectMask(TextureSource *aMaskTexture, |
michael@0 | 81 | gfx::IntSize aSize, |
michael@0 | 82 | const gfx::Matrix4x4 &aMaskTransform) |
michael@0 | 83 | : Effect(EFFECT_MASK) |
michael@0 | 84 | , mMaskTexture(aMaskTexture) |
michael@0 | 85 | , mIs3D(false) |
michael@0 | 86 | , mSize(aSize) |
michael@0 | 87 | , mMaskTransform(aMaskTransform) |
michael@0 | 88 | {} |
michael@0 | 89 | |
michael@0 | 90 | virtual void PrintInfo(nsACString& aTo, const char* aPrefix); |
michael@0 | 91 | |
michael@0 | 92 | TextureSource* mMaskTexture; |
michael@0 | 93 | bool mIs3D; |
michael@0 | 94 | gfx::IntSize mSize; |
michael@0 | 95 | gfx::Matrix4x4 mMaskTransform; |
michael@0 | 96 | }; |
michael@0 | 97 | |
michael@0 | 98 | // Render to a render target rather than the screen. |
michael@0 | 99 | struct EffectRenderTarget : public TexturedEffect |
michael@0 | 100 | { |
michael@0 | 101 | EffectRenderTarget(CompositingRenderTarget *aRenderTarget) |
michael@0 | 102 | : TexturedEffect(EFFECT_RENDER_TARGET, aRenderTarget, true, gfx::Filter::LINEAR) |
michael@0 | 103 | , mRenderTarget(aRenderTarget) |
michael@0 | 104 | {} |
michael@0 | 105 | |
michael@0 | 106 | virtual const char* Name() { return "EffectRenderTarget"; } |
michael@0 | 107 | virtual void PrintInfo(nsACString& aTo, const char* aPrefix); |
michael@0 | 108 | |
michael@0 | 109 | RefPtr<CompositingRenderTarget> mRenderTarget; |
michael@0 | 110 | }; |
michael@0 | 111 | |
michael@0 | 112 | struct EffectRGB : public TexturedEffect |
michael@0 | 113 | { |
michael@0 | 114 | EffectRGB(TextureSource *aTexture, |
michael@0 | 115 | bool aPremultiplied, |
michael@0 | 116 | gfx::Filter aFilter, |
michael@0 | 117 | bool aFlipped = false) |
michael@0 | 118 | : TexturedEffect(EFFECT_RGB, aTexture, aPremultiplied, aFilter) |
michael@0 | 119 | {} |
michael@0 | 120 | |
michael@0 | 121 | virtual const char* Name() { return "EffectRGB"; } |
michael@0 | 122 | }; |
michael@0 | 123 | |
michael@0 | 124 | struct EffectYCbCr : public TexturedEffect |
michael@0 | 125 | { |
michael@0 | 126 | EffectYCbCr(TextureSource *aSource, gfx::Filter aFilter) |
michael@0 | 127 | : TexturedEffect(EFFECT_YCBCR, aSource, false, aFilter) |
michael@0 | 128 | {} |
michael@0 | 129 | |
michael@0 | 130 | virtual const char* Name() { return "EffectYCbCr"; } |
michael@0 | 131 | }; |
michael@0 | 132 | |
michael@0 | 133 | struct EffectComponentAlpha : public TexturedEffect |
michael@0 | 134 | { |
michael@0 | 135 | EffectComponentAlpha(TextureSource *aOnBlack, |
michael@0 | 136 | TextureSource *aOnWhite, |
michael@0 | 137 | gfx::Filter aFilter) |
michael@0 | 138 | : TexturedEffect(EFFECT_COMPONENT_ALPHA, nullptr, false, aFilter) |
michael@0 | 139 | , mOnBlack(aOnBlack) |
michael@0 | 140 | , mOnWhite(aOnWhite) |
michael@0 | 141 | {} |
michael@0 | 142 | |
michael@0 | 143 | virtual const char* Name() { return "EffectComponentAlpha"; } |
michael@0 | 144 | |
michael@0 | 145 | TextureSource* mOnBlack; |
michael@0 | 146 | TextureSource* mOnWhite; |
michael@0 | 147 | }; |
michael@0 | 148 | |
michael@0 | 149 | struct EffectSolidColor : public Effect |
michael@0 | 150 | { |
michael@0 | 151 | EffectSolidColor(const gfx::Color &aColor) |
michael@0 | 152 | : Effect(EFFECT_SOLID_COLOR) |
michael@0 | 153 | , mColor(aColor) |
michael@0 | 154 | {} |
michael@0 | 155 | |
michael@0 | 156 | virtual void PrintInfo(nsACString& aTo, const char* aPrefix); |
michael@0 | 157 | |
michael@0 | 158 | gfx::Color mColor; |
michael@0 | 159 | }; |
michael@0 | 160 | |
michael@0 | 161 | struct EffectChain |
michael@0 | 162 | { |
michael@0 | 163 | EffectChain() : mLayerRef(nullptr) {} |
michael@0 | 164 | explicit EffectChain(void* aLayerRef) : mLayerRef(aLayerRef) {} |
michael@0 | 165 | |
michael@0 | 166 | RefPtr<Effect> mPrimaryEffect; |
michael@0 | 167 | RefPtr<Effect> mSecondaryEffects[EFFECT_MAX_SECONDARY]; |
michael@0 | 168 | void* mLayerRef; //!< For LayerScope logging |
michael@0 | 169 | }; |
michael@0 | 170 | |
michael@0 | 171 | /** |
michael@0 | 172 | * Create a Textured effect corresponding to aFormat and using |
michael@0 | 173 | * aSource as the (first) texture source. |
michael@0 | 174 | * |
michael@0 | 175 | * Note that aFormat can be different form aSource->GetFormat if, we are |
michael@0 | 176 | * creating an effect that takes several texture sources (like with YCBCR |
michael@0 | 177 | * where aFormat would be FOMRAT_YCBCR and each texture source would be |
michael@0 | 178 | * a one-channel A8 texture) |
michael@0 | 179 | */ |
michael@0 | 180 | inline TemporaryRef<TexturedEffect> |
michael@0 | 181 | CreateTexturedEffect(gfx::SurfaceFormat aFormat, |
michael@0 | 182 | TextureSource* aSource, |
michael@0 | 183 | const gfx::Filter& aFilter) |
michael@0 | 184 | { |
michael@0 | 185 | MOZ_ASSERT(aSource); |
michael@0 | 186 | RefPtr<TexturedEffect> result; |
michael@0 | 187 | switch (aFormat) { |
michael@0 | 188 | case gfx::SurfaceFormat::B8G8R8A8: |
michael@0 | 189 | case gfx::SurfaceFormat::B8G8R8X8: |
michael@0 | 190 | case gfx::SurfaceFormat::R8G8B8X8: |
michael@0 | 191 | case gfx::SurfaceFormat::R5G6B5: |
michael@0 | 192 | case gfx::SurfaceFormat::R8G8B8A8: |
michael@0 | 193 | result = new EffectRGB(aSource, true, aFilter); |
michael@0 | 194 | break; |
michael@0 | 195 | case gfx::SurfaceFormat::YUV: |
michael@0 | 196 | result = new EffectYCbCr(aSource, aFilter); |
michael@0 | 197 | break; |
michael@0 | 198 | default: |
michael@0 | 199 | NS_WARNING("unhandled program type"); |
michael@0 | 200 | break; |
michael@0 | 201 | } |
michael@0 | 202 | |
michael@0 | 203 | return result; |
michael@0 | 204 | } |
michael@0 | 205 | |
michael@0 | 206 | /** |
michael@0 | 207 | * Create a textured effect based on aSource format and the presence of |
michael@0 | 208 | * aSourceOnWhite. |
michael@0 | 209 | * |
michael@0 | 210 | * aSourceOnWhite can be null. |
michael@0 | 211 | */ |
michael@0 | 212 | inline TemporaryRef<TexturedEffect> |
michael@0 | 213 | CreateTexturedEffect(TextureSource* aSource, |
michael@0 | 214 | TextureSource* aSourceOnWhite, |
michael@0 | 215 | const gfx::Filter& aFilter) |
michael@0 | 216 | { |
michael@0 | 217 | MOZ_ASSERT(aSource); |
michael@0 | 218 | if (aSourceOnWhite) { |
michael@0 | 219 | MOZ_ASSERT(aSource->GetFormat() == gfx::SurfaceFormat::R8G8B8X8 || |
michael@0 | 220 | aSourceOnWhite->GetFormat() == gfx::SurfaceFormat::B8G8R8X8); |
michael@0 | 221 | return new EffectComponentAlpha(aSource, aSourceOnWhite, aFilter); |
michael@0 | 222 | } |
michael@0 | 223 | |
michael@0 | 224 | return CreateTexturedEffect(aSource->GetFormat(), aSource, aFilter); |
michael@0 | 225 | } |
michael@0 | 226 | |
michael@0 | 227 | /** |
michael@0 | 228 | * Create a textured effect based on aSource format. |
michael@0 | 229 | * |
michael@0 | 230 | * This version excudes the possibility of component alpha. |
michael@0 | 231 | */ |
michael@0 | 232 | inline TemporaryRef<TexturedEffect> |
michael@0 | 233 | CreateTexturedEffect(TextureSource *aTexture, |
michael@0 | 234 | const gfx::Filter& aFilter) |
michael@0 | 235 | { |
michael@0 | 236 | return CreateTexturedEffect(aTexture, nullptr, aFilter); |
michael@0 | 237 | } |
michael@0 | 238 | |
michael@0 | 239 | |
michael@0 | 240 | } // namespace layers |
michael@0 | 241 | } // namespace mozilla |
michael@0 | 242 | |
michael@0 | 243 | #endif |