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 "PaintedLayerComposite.h"
8 #include "CompositableHost.h" // for TiledLayerProperties, etc
9 #include "FrameMetrics.h" // for FrameMetrics
10 #include "Units.h" // for CSSRect, LayerPixel, etc
11 #include "gfxEnv.h" // for gfxEnv
12 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
13 #include "mozilla/gfx/Matrix.h" // for Matrix4x4
14 #include "mozilla/gfx/Point.h" // for Point
15 #include "mozilla/gfx/Polygon.h" // for Polygon
16 #include "mozilla/gfx/Rect.h" // for RoundedToInt, Rect
17 #include "mozilla/gfx/Types.h" // for SamplingFilter::LINEAR
18 #include "mozilla/layers/Compositor.h" // for Compositor
19 #include "mozilla/layers/ContentHost.h" // for ContentHost
20 #include "mozilla/layers/Effects.h" // for EffectChain
21 #include "mozilla/layers/LayerManagerCompositeUtils.h"
22 #include "mozilla/mozalloc.h" // for operator delete
23 #include "mozilla/ProfilerLabels.h"
24 #include "nsAString.h"
25 #include "mozilla/RefPtr.h" // for nsRefPtr
26 #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
27 #include "nsMathUtils.h" // for NS_lround
28 #include "nsString.h" // for nsAutoCString
29 #include "TextRenderer.h"
30
31 namespace mozilla {
32 namespace layers {
33
PaintedLayerComposite(LayerManagerComposite * aManager)34 PaintedLayerComposite::PaintedLayerComposite(LayerManagerComposite* aManager)
35 : PaintedLayer(aManager, nullptr),
36 LayerComposite(aManager),
37 mBuffer(nullptr) {
38 MOZ_COUNT_CTOR(PaintedLayerComposite);
39 mImplData = static_cast<LayerComposite*>(this);
40 }
41
~PaintedLayerComposite()42 PaintedLayerComposite::~PaintedLayerComposite() {
43 MOZ_COUNT_DTOR(PaintedLayerComposite);
44 CleanupResources();
45 }
46
SetCompositableHost(CompositableHost * aHost)47 bool PaintedLayerComposite::SetCompositableHost(CompositableHost* aHost) {
48 switch (aHost->GetType()) {
49 case CompositableType::CONTENT_TILED:
50 case CompositableType::CONTENT_SINGLE:
51 case CompositableType::CONTENT_DOUBLE: {
52 ContentHost* newBuffer = static_cast<ContentHost*>(aHost);
53 if (mBuffer && newBuffer != mBuffer) {
54 mBuffer->Detach(this);
55 }
56 mBuffer = newBuffer;
57 return true;
58 }
59 default:
60 return false;
61 }
62 }
63
Disconnect()64 void PaintedLayerComposite::Disconnect() { Destroy(); }
65
Destroy()66 void PaintedLayerComposite::Destroy() {
67 if (!mDestroyed) {
68 CleanupResources();
69 mDestroyed = true;
70 }
71 }
72
GetLayer()73 Layer* PaintedLayerComposite::GetLayer() { return this; }
74
SetLayerManager(HostLayerManager * aManager)75 void PaintedLayerComposite::SetLayerManager(HostLayerManager* aManager) {
76 LayerComposite::SetLayerManager(aManager);
77 mManager = aManager;
78 if (mBuffer && mCompositor) {
79 mBuffer->SetTextureSourceProvider(mCompositor);
80 }
81 }
82
RenderLayer(const gfx::IntRect & aClipRect,const Maybe<gfx::Polygon> & aGeometry)83 void PaintedLayerComposite::RenderLayer(const gfx::IntRect& aClipRect,
84 const Maybe<gfx::Polygon>& aGeometry) {
85 if (!mBuffer || !mBuffer->IsAttached()) {
86 return;
87 }
88 AUTO_PROFILER_LABEL("PaintedLayerComposite::RenderLayer", GRAPHICS);
89
90 Compositor* compositor = mCompositeManager->GetCompositor();
91
92 MOZ_ASSERT(mBuffer->GetTextureSourceProvider() == compositor &&
93 mBuffer->GetLayer() == this,
94 "buffer is corrupted");
95
96 const nsIntRegion visibleRegion = GetLocalVisibleRegion().ToUnknownRegion();
97
98 #ifdef MOZ_DUMP_PAINTING
99 if (gfxEnv::DumpCompositorTextures()) {
100 RefPtr<gfx::DataSourceSurface> surf = mBuffer->GetAsSurface();
101 if (surf) {
102 WriteSnapshotToDumpFile(this, surf);
103 }
104 }
105 #endif
106
107 RenderWithAllMasks(
108 this, compositor, aClipRect,
109 [&](EffectChain& effectChain, const gfx::IntRect& clipRect) {
110 mBuffer->SetPaintWillResample(MayResample());
111
112 mBuffer->Composite(compositor, this, effectChain, GetEffectiveOpacity(),
113 GetEffectiveTransform(), GetSamplingFilter(),
114 clipRect, &visibleRegion, aGeometry);
115 });
116
117 mBuffer->BumpFlashCounter();
118
119 compositor->MakeCurrent();
120 }
121
GetCompositableHost()122 CompositableHost* PaintedLayerComposite::GetCompositableHost() {
123 if (mBuffer && mBuffer->IsAttached()) {
124 return mBuffer.get();
125 }
126
127 return nullptr;
128 }
129
CleanupResources()130 void PaintedLayerComposite::CleanupResources() {
131 if (mBuffer) {
132 mBuffer->Detach(this);
133 }
134 mBuffer = nullptr;
135 }
136
IsOpaque()137 bool PaintedLayerComposite::IsOpaque() {
138 if (!mBuffer || !mBuffer->IsAttached()) {
139 return false;
140 }
141 return PaintedLayer::IsOpaque();
142 }
143
GenEffectChain(EffectChain & aEffect)144 void PaintedLayerComposite::GenEffectChain(EffectChain& aEffect) {
145 aEffect.mLayerRef = this;
146 aEffect.mPrimaryEffect = mBuffer->GenEffect(GetSamplingFilter());
147 }
148
PrintInfo(std::stringstream & aStream,const char * aPrefix)149 void PaintedLayerComposite::PrintInfo(std::stringstream& aStream,
150 const char* aPrefix) {
151 PaintedLayer::PrintInfo(aStream, aPrefix);
152 if (mBuffer && mBuffer->IsAttached()) {
153 aStream << "\n";
154 nsAutoCString pfx(aPrefix);
155 pfx += " ";
156 mBuffer->PrintInfo(aStream, pfx.get());
157 }
158 }
159
GetInvalidRegion()160 const gfx::TiledIntRegion& PaintedLayerComposite::GetInvalidRegion() {
161 if (mBuffer) {
162 nsIntRegion region = mInvalidRegion.GetRegion();
163 mBuffer->AddAnimationInvalidation(region);
164 }
165 return mInvalidRegion;
166 }
167
168 } // namespace layers
169 } // namespace mozilla
170