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 #include "CompositableHost.h"
8 #include <map> // for _Rb_tree_iterator, map, etc
9 #include <utility> // for pair
10 #include "ContentHost.h" // for ContentHostDoubleBuffered, etc
11 #include "Effects.h" // for EffectMask, Effect, etc
12 #include "gfxUtils.h"
13 #include "ImageHost.h" // for ImageHostBuffered, etc
14 #include "Layers.h"
15 #include "TiledContentHost.h" // for TiledContentHost
16 #include "mozilla/EndianUtils.h"
17 #include "mozilla/gfx/gfxVars.h"
18 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
19 #include "mozilla/layers/TextureHost.h" // for TextureHost, etc
20 #include "mozilla/layers/WebRenderImageHost.h"
21 #include "mozilla/RefPtr.h" // for nsRefPtr
22 #include "nsDebug.h" // for NS_WARNING
23 #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
24 #include "gfxPlatform.h" // for gfxPlatform
25 #include "IPDLActor.h"
26
27 namespace mozilla {
28
29 using namespace gfx;
30
31 namespace layers {
32
33 class Compositor;
34
CompositableHost(const TextureInfo & aTextureInfo)35 CompositableHost::CompositableHost(const TextureInfo& aTextureInfo)
36 : mTextureInfo(aTextureInfo),
37 mCompositorBridgeID(0),
38 mLayer(nullptr),
39 mFlashCounter(0),
40 mAttached(false),
41 mKeepAttached(false) {
42 MOZ_COUNT_CTOR(CompositableHost);
43 }
44
~CompositableHost()45 CompositableHost::~CompositableHost() { MOZ_COUNT_DTOR(CompositableHost); }
46
UseTextureHost(const nsTArray<TimedTexture> & aTextures)47 void CompositableHost::UseTextureHost(const nsTArray<TimedTexture>& aTextures) {
48 if (mTextureSourceProvider) {
49 for (auto& texture : aTextures) {
50 texture.mTexture->SetTextureSourceProvider(mTextureSourceProvider);
51 }
52 }
53 }
54
UseComponentAlphaTextures(TextureHost * aTextureOnBlack,TextureHost * aTextureOnWhite)55 void CompositableHost::UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
56 TextureHost* aTextureOnWhite) {
57 MOZ_ASSERT(aTextureOnBlack && aTextureOnWhite);
58 if (mTextureSourceProvider) {
59 aTextureOnBlack->SetTextureSourceProvider(mTextureSourceProvider);
60 aTextureOnWhite->SetTextureSourceProvider(mTextureSourceProvider);
61 }
62 }
63
RemoveTextureHost(TextureHost * aTexture)64 void CompositableHost::RemoveTextureHost(TextureHost* aTexture) {}
65
SetTextureSourceProvider(TextureSourceProvider * aProvider)66 void CompositableHost::SetTextureSourceProvider(
67 TextureSourceProvider* aProvider) {
68 MOZ_ASSERT(aProvider);
69 mTextureSourceProvider = aProvider;
70 }
71
AddMaskEffect(EffectChain & aEffects,const gfx::Matrix4x4 & aTransform)72 bool CompositableHost::AddMaskEffect(EffectChain& aEffects,
73 const gfx::Matrix4x4& aTransform) {
74 CompositableTextureSourceRef source;
75 RefPtr<TextureHost> host = GetAsTextureHost();
76
77 if (!host) {
78 NS_WARNING("Using compositable with no valid TextureHost as mask");
79 return false;
80 }
81
82 if (!host->Lock()) {
83 NS_WARNING("Failed to lock the mask texture");
84 return false;
85 }
86
87 if (!host->BindTextureSource(source)) {
88 NS_WARNING(
89 "The TextureHost was successfully locked but can't provide a "
90 "TextureSource");
91 host->Unlock();
92 return false;
93 }
94 MOZ_ASSERT(source);
95
96 // Setting an alpha-mask here breaks the URL-bar on big endian (s390x)
97 // if the typed URL is too long for the textbox (automatic scrolling needed)
98 #if MOZ_LITTLE_ENDIAN()
99 RefPtr<EffectMask> effect =
100 new EffectMask(source, source->GetSize(), aTransform);
101 aEffects.mSecondaryEffects[EffectTypes::MASK] = effect;
102 #endif
103 return true;
104 }
105
RemoveMaskEffect()106 void CompositableHost::RemoveMaskEffect() {
107 RefPtr<TextureHost> host = GetAsTextureHost();
108 if (host) {
109 host->Unlock();
110 }
111 }
112
113 /* static */
Create(const TextureInfo & aTextureInfo,bool aUseWebRender)114 already_AddRefed<CompositableHost> CompositableHost::Create(
115 const TextureInfo& aTextureInfo, bool aUseWebRender) {
116 RefPtr<CompositableHost> result;
117 switch (aTextureInfo.mCompositableType) {
118 case CompositableType::IMAGE_BRIDGE:
119 NS_ERROR("Cannot create an image bridge compositable this way");
120 break;
121 case CompositableType::CONTENT_TILED:
122 result = new TiledContentHost(aTextureInfo);
123 break;
124 case CompositableType::IMAGE:
125 if (aUseWebRender) {
126 result = new WebRenderImageHost(aTextureInfo);
127 } else {
128 result = new ImageHost(aTextureInfo);
129 }
130 break;
131 case CompositableType::CONTENT_SINGLE:
132 if (aUseWebRender) {
133 result = new WebRenderImageHost(aTextureInfo);
134 } else {
135 result = new ContentHostSingleBuffered(aTextureInfo);
136 }
137 break;
138 case CompositableType::CONTENT_DOUBLE:
139 MOZ_ASSERT(!aUseWebRender);
140 result = new ContentHostDoubleBuffered(aTextureInfo);
141 break;
142 default:
143 NS_ERROR("Unknown CompositableType");
144 }
145 return result.forget();
146 }
147
DumpTextureHost(std::stringstream & aStream,TextureHost * aTexture)148 void CompositableHost::DumpTextureHost(std::stringstream& aStream,
149 TextureHost* aTexture) {
150 if (!aTexture) {
151 return;
152 }
153 RefPtr<gfx::DataSourceSurface> dSurf = aTexture->GetAsSurface();
154 if (!dSurf) {
155 return;
156 }
157 aStream << gfxUtils::GetAsDataURI(dSurf).get();
158 }
159
GetLayerManager() const160 HostLayerManager* CompositableHost::GetLayerManager() const {
161 if (!mLayer || !mLayer->Manager()) {
162 return nullptr;
163 }
164 return mLayer->Manager()->AsHostLayerManager();
165 }
166
GetTextureSourceProvider() const167 TextureSourceProvider* CompositableHost::GetTextureSourceProvider() const {
168 return mTextureSourceProvider;
169 }
170
171 } // namespace layers
172 } // namespace mozilla
173