Effects.h (7650B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef MOZILLA_LAYERS_EFFECTS_H 8 #define MOZILLA_LAYERS_EFFECTS_H 9 10 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc 11 #include "mozilla/RefPtr.h" // for RefPtr, already_AddRefed, etc 12 #include "mozilla/gfx/Matrix.h" // for Matrix4x4 13 #include "mozilla/gfx/Point.h" // for IntSize 14 #include "mozilla/gfx/Rect.h" // for Rect 15 #include "mozilla/gfx/Types.h" // for SamplingFilter, etc 16 #include "mozilla/layers/CompositorTypes.h" // for EffectTypes, etc 17 #include "mozilla/layers/TextureHost.h" // for CompositingRenderTarget, etc 18 #include "mozilla/mozalloc.h" // for operator delete, etc 19 #include "nscore.h" // for nsACString 20 21 namespace mozilla { 22 namespace layers { 23 24 /** 25 * Effects and effect chains are used by the compositor API (see Compositor.h). 26 * An effect chain represents a rendering method, for example some shader and 27 * the data required for that shader to run. An effect is some component of the 28 * chain and its data. 29 * 30 * An effect chain consists of a primary effect - how the 'texture' memory 31 * should be interpreted (RGBA, BGRX, YCBCR, etc.) - and any number of secondary 32 * effects 33 * - any way in which rendering can be changed, e.g., applying a mask layer. 34 * 35 * During the rendering process, an effect chain is created by the layer being 36 * rendered and the primary effect is added by the compositable host. Secondary 37 * effects may be added by the layer or compositable. The effect chain is passed 38 * to the compositor by the compositable host as a parameter to DrawQuad. 39 */ 40 41 struct TexturedEffect; 42 43 struct Effect { 44 NS_INLINE_DECL_REFCOUNTING(Effect) 45 46 explicit Effect(EffectTypes aType) : mType(aType) {} 47 48 EffectTypes mType; 49 50 virtual TexturedEffect* AsTexturedEffect() { return nullptr; } 51 virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) = 0; 52 53 protected: 54 virtual ~Effect() = default; 55 }; 56 57 // Render from a texture 58 struct TexturedEffect : public Effect { 59 TexturedEffect(EffectTypes aType, TextureSource* aTexture, 60 bool aPremultiplied, gfx::SamplingFilter aSamplingFilter) 61 : Effect(aType), 62 mTextureCoords(0, 0, 1.0f, 1.0f), 63 mTexture(aTexture), 64 mPremultiplied(aPremultiplied), 65 mPremultipliedCopy(false), 66 mSamplingFilter(aSamplingFilter) {} 67 68 TexturedEffect* AsTexturedEffect() override { return this; } 69 virtual const char* Name() = 0; 70 void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; 71 72 gfx::Rect mTextureCoords; 73 TextureSource* mTexture; 74 bool mPremultiplied; 75 bool mPremultipliedCopy; 76 gfx::SamplingFilter mSamplingFilter; 77 }; 78 79 struct EffectRGB : public TexturedEffect { 80 EffectRGB(TextureSource* aTexture, bool aPremultiplied, 81 gfx::SamplingFilter aSamplingFilter, bool aFlipped = false) 82 : TexturedEffect(EffectTypes::RGB, aTexture, aPremultiplied, 83 aSamplingFilter) {} 84 85 const char* Name() override { return "EffectRGB"; } 86 }; 87 88 struct EffectYCbCr : public TexturedEffect { 89 EffectYCbCr(TextureSource* aSource, gfx::YUVColorSpace aYUVColorSpace, 90 gfx::ColorRange aColorRange, gfx::ColorDepth aColorDepth, 91 gfx::SamplingFilter aSamplingFilter) 92 : TexturedEffect(EffectTypes::YCBCR, aSource, false, aSamplingFilter), 93 mYUVColorSpace(aYUVColorSpace), 94 mColorRange(aColorRange), 95 mColorDepth(aColorDepth) {} 96 97 const char* Name() override { return "EffectYCbCr"; } 98 99 gfx::YUVColorSpace mYUVColorSpace; 100 gfx::ColorRange mColorRange; 101 gfx::ColorDepth mColorDepth; 102 }; 103 104 struct EffectNV12 : public EffectYCbCr { 105 EffectNV12(TextureSource* aSource, gfx::YUVColorSpace aYUVColorSpace, 106 gfx::ColorRange aColorRange, gfx::ColorDepth aColorDepth, 107 gfx::SamplingFilter aSamplingFilter) 108 : EffectYCbCr(aSource, aYUVColorSpace, aColorRange, aColorDepth, 109 aSamplingFilter) { 110 mType = EffectTypes::NV12; 111 } 112 113 const char* Name() override { return "EffectNV12"; } 114 }; 115 116 struct EffectRoundedClip : public Effect { 117 explicit EffectRoundedClip(const gfx::Rect& aRect, 118 const gfx::RectCornerRadii& aRadii) 119 : Effect(EffectTypes::ROUNDED_CLIP), mRect(aRect), mRadii(aRadii) {} 120 121 virtual const char* Name() { return "EffectRoundedClip"; } 122 void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; 123 124 gfx::Rect mRect; 125 gfx::RectCornerRadii mRadii; 126 }; 127 128 struct EffectChain { 129 RefPtr<Effect> mPrimaryEffect; 130 RefPtr<EffectRoundedClip> mRoundedClipEffect; 131 }; 132 133 /** 134 * Create a Textured effect corresponding to aFormat and using 135 * aSource as the (first) texture source. 136 * 137 * Note that aFormat can be different form aSource->GetFormat if, we are 138 * creating an effect that takes several texture sources (like with YCBCR 139 * where aFormat would be FORMAT_YCBCR and each texture source would be 140 * a one-channel A8 texture) 141 */ 142 inline already_AddRefed<TexturedEffect> CreateTexturedEffect( 143 gfx::SurfaceFormat aFormat, TextureSource* aSource, 144 const gfx::SamplingFilter aSamplingFilter, bool isAlphaPremultiplied) { 145 MOZ_ASSERT(aSource); 146 RefPtr<TexturedEffect> result; 147 switch (aFormat) { 148 case gfx::SurfaceFormat::B8G8R8A8: 149 case gfx::SurfaceFormat::B8G8R8X8: 150 case gfx::SurfaceFormat::R8G8B8X8: 151 case gfx::SurfaceFormat::R5G6B5_UINT16: 152 case gfx::SurfaceFormat::R8G8B8A8: 153 result = new EffectRGB(aSource, isAlphaPremultiplied, aSamplingFilter); 154 break; 155 case gfx::SurfaceFormat::YUV420: 156 case gfx::SurfaceFormat::NV12: 157 case gfx::SurfaceFormat::P010: 158 case gfx::SurfaceFormat::P016: 159 MOZ_ASSERT_UNREACHABLE( 160 "gfx::SurfaceFormat::YUV420/NV12/P010/P016 is invalid"); 161 break; 162 default: 163 NS_WARNING("unhandled program type"); 164 break; 165 } 166 167 return result.forget(); 168 } 169 170 inline already_AddRefed<TexturedEffect> CreateTexturedEffect( 171 TextureHost* aHost, TextureSource* aSource, 172 const gfx::SamplingFilter aSamplingFilter, bool isAlphaPremultiplied) { 173 MOZ_ASSERT(aHost); 174 MOZ_ASSERT(aSource); 175 176 RefPtr<TexturedEffect> result; 177 178 switch (aHost->GetReadFormat()) { 179 case gfx::SurfaceFormat::YUV420: 180 result = new EffectYCbCr(aSource, aHost->GetYUVColorSpace(), 181 aHost->GetColorRange(), aHost->GetColorDepth(), 182 aSamplingFilter); 183 break; 184 case gfx::SurfaceFormat::NV12: 185 case gfx::SurfaceFormat::P010: 186 case gfx::SurfaceFormat::P016: 187 result = new EffectNV12(aSource, aHost->GetYUVColorSpace(), 188 aHost->GetColorRange(), aHost->GetColorDepth(), 189 aSamplingFilter); 190 break; 191 default: 192 result = CreateTexturedEffect(aHost->GetReadFormat(), aSource, 193 aSamplingFilter, isAlphaPremultiplied); 194 break; 195 } 196 return result.forget(); 197 } 198 199 /** 200 * Create a textured effect based on aSource format. 201 * 202 * This version excudes the possibility of component alpha. 203 */ 204 inline already_AddRefed<TexturedEffect> CreateTexturedEffect( 205 TextureSource* aTexture, const gfx::SamplingFilter aSamplingFilter) { 206 return CreateTexturedEffect(aTexture->GetFormat(), aTexture, aSamplingFilter, 207 true); 208 } 209 210 } // namespace layers 211 } // namespace mozilla 212 213 #endif