1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "PaintedLayerComposite.h"
7 #include "CompositableHost.h"           // for TiledLayerProperties, etc
8 #include "FrameMetrics.h"               // for FrameMetrics
9 #include "Units.h"                      // for CSSRect, LayerPixel, etc
10 #include "gfxEnv.h"                     // for gfxEnv
11 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
12 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
13 #include "mozilla/gfx/Point.h"          // for Point
14 #include "mozilla/gfx/Rect.h"           // for RoundedToInt, Rect
15 #include "mozilla/gfx/Types.h"          // for SamplingFilter::LINEAR
16 #include "mozilla/layers/Compositor.h"  // for Compositor
17 #include "mozilla/layers/ContentHost.h"  // for ContentHost
18 #include "mozilla/layers/Effects.h"     // for EffectChain
19 #include "mozilla/mozalloc.h"           // for operator delete
20 #include "nsAString.h"
21 #include "mozilla/RefPtr.h"                   // for nsRefPtr
22 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
23 #include "nsMathUtils.h"                // for NS_lround
24 #include "nsString.h"                   // for nsAutoCString
25 #include "TextRenderer.h"
26 #include "GeckoProfiler.h"
27 
28 namespace mozilla {
29 namespace layers {
30 
PaintedLayerComposite(LayerManagerComposite * aManager)31 PaintedLayerComposite::PaintedLayerComposite(LayerManagerComposite *aManager)
32   : PaintedLayer(aManager, nullptr)
33   , LayerComposite(aManager)
34   , mBuffer(nullptr)
35 {
36   MOZ_COUNT_CTOR(PaintedLayerComposite);
37   mImplData = static_cast<LayerComposite*>(this);
38 }
39 
~PaintedLayerComposite()40 PaintedLayerComposite::~PaintedLayerComposite()
41 {
42   MOZ_COUNT_DTOR(PaintedLayerComposite);
43   CleanupResources();
44 }
45 
46 bool
SetCompositableHost(CompositableHost * aHost)47 PaintedLayerComposite::SetCompositableHost(CompositableHost* aHost)
48 {
49   switch (aHost->GetType()) {
50     case CompositableType::CONTENT_TILED:
51     case CompositableType::CONTENT_SINGLE:
52     case CompositableType::CONTENT_DOUBLE:
53       mBuffer = static_cast<ContentHost*>(aHost);
54       return true;
55     default:
56       return false;
57   }
58 }
59 
60 void
Disconnect()61 PaintedLayerComposite::Disconnect()
62 {
63   Destroy();
64 }
65 
66 void
Destroy()67 PaintedLayerComposite::Destroy()
68 {
69   if (!mDestroyed) {
70     CleanupResources();
71     mDestroyed = true;
72   }
73 }
74 
75 Layer*
GetLayer()76 PaintedLayerComposite::GetLayer()
77 {
78   return this;
79 }
80 
81 void
SetLayerManager(LayerManagerComposite * aManager)82 PaintedLayerComposite::SetLayerManager(LayerManagerComposite* aManager)
83 {
84   LayerComposite::SetLayerManager(aManager);
85   mManager = aManager;
86   if (mBuffer && mCompositor) {
87     mBuffer->SetCompositor(mCompositor);
88   }
89 }
90 
91 LayerRenderState
GetRenderState()92 PaintedLayerComposite::GetRenderState()
93 {
94   if (!mBuffer || !mBuffer->IsAttached() || mDestroyed) {
95     return LayerRenderState();
96   }
97   return mBuffer->GetRenderState();
98 }
99 
100 void
RenderLayer(const gfx::IntRect & aClipRect)101 PaintedLayerComposite::RenderLayer(const gfx::IntRect& aClipRect)
102 {
103   if (!mBuffer || !mBuffer->IsAttached()) {
104     return;
105   }
106   PROFILER_LABEL("PaintedLayerComposite", "RenderLayer",
107     js::ProfileEntry::Category::GRAPHICS);
108 
109   Compositor* compositor = mCompositeManager->GetCompositor();
110 
111   MOZ_ASSERT(mBuffer->GetCompositor() == compositor &&
112              mBuffer->GetLayer() == this,
113              "buffer is corrupted");
114 
115   const nsIntRegion visibleRegion = GetLocalVisibleRegion().ToUnknownRegion();
116 
117 #ifdef MOZ_DUMP_PAINTING
118   if (gfxEnv::DumpCompositorTextures()) {
119     RefPtr<gfx::DataSourceSurface> surf = mBuffer->GetAsSurface();
120     if (surf) {
121       WriteSnapshotToDumpFile(this, surf);
122     }
123   }
124 #endif
125 
126 
127   RenderWithAllMasks(this, compositor, aClipRect,
128                      [&](EffectChain& effectChain, const gfx::IntRect& clipRect) {
129     mBuffer->SetPaintWillResample(MayResample());
130 
131     mBuffer->Composite(this, effectChain,
132                        GetEffectiveOpacity(),
133                        GetEffectiveTransform(),
134                        GetSamplingFilter(),
135                        clipRect,
136                        &visibleRegion);
137   });
138 
139   mBuffer->BumpFlashCounter();
140 
141   compositor->MakeCurrent();
142 }
143 
144 CompositableHost*
GetCompositableHost()145 PaintedLayerComposite::GetCompositableHost()
146 {
147   if (mBuffer && mBuffer->IsAttached()) {
148     return mBuffer.get();
149   }
150 
151   return nullptr;
152 }
153 
154 void
CleanupResources()155 PaintedLayerComposite::CleanupResources()
156 {
157   if (mBuffer) {
158     mBuffer->Detach(this);
159   }
160   mBuffer = nullptr;
161 }
162 
163 void
GenEffectChain(EffectChain & aEffect)164 PaintedLayerComposite::GenEffectChain(EffectChain& aEffect)
165 {
166   aEffect.mLayerRef = this;
167   aEffect.mPrimaryEffect = mBuffer->GenEffect(GetSamplingFilter());
168 }
169 
170 void
PrintInfo(std::stringstream & aStream,const char * aPrefix)171 PaintedLayerComposite::PrintInfo(std::stringstream& aStream, const char* aPrefix)
172 {
173   PaintedLayer::PrintInfo(aStream, aPrefix);
174   if (mBuffer && mBuffer->IsAttached()) {
175     aStream << "\n";
176     nsAutoCString pfx(aPrefix);
177     pfx += "  ";
178     mBuffer->PrintInfo(aStream, pfx.get());
179   }
180 }
181 
182 const gfx::TiledIntRegion&
GetInvalidRegion()183 PaintedLayerComposite::GetInvalidRegion()
184 {
185   if (mBuffer) {
186     nsIntRegion region = mInvalidRegion.GetRegion();
187     mBuffer->AddAnimationInvalidation(region);
188   }
189   return mInvalidRegion;
190 }
191 
192 
193 } // namespace layers
194 } // namespace mozilla
195