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