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