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