/src/mozilla-central/gfx/layers/mlgpu/PaintedLayerMLGPU.cpp
Line | Count | Source (jump to first uncovered line) |
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 "PaintedLayerMLGPU.h" |
8 | | #include "LayerManagerMLGPU.h" |
9 | | #include "mozilla/layers/LayersHelpers.h" |
10 | | #include "mozilla/layers/TiledContentHost.h" |
11 | | #include "UnitTransforms.h" |
12 | | |
13 | | namespace mozilla { |
14 | | |
15 | | using namespace gfx; |
16 | | |
17 | | namespace layers { |
18 | | |
19 | | PaintedLayerMLGPU::PaintedLayerMLGPU(LayerManagerMLGPU* aManager) |
20 | | : PaintedLayer(aManager, static_cast<HostLayer*>(this)), |
21 | | LayerMLGPU(aManager) |
22 | 0 | { |
23 | 0 | MOZ_COUNT_CTOR(PaintedLayerMLGPU); |
24 | 0 | } |
25 | | |
26 | | PaintedLayerMLGPU::~PaintedLayerMLGPU() |
27 | 0 | { |
28 | 0 | MOZ_COUNT_DTOR(PaintedLayerMLGPU); |
29 | 0 |
|
30 | 0 | CleanupResources(); |
31 | 0 | } |
32 | | |
33 | | bool |
34 | | PaintedLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder) |
35 | 0 | { |
36 | 0 | // Reset our cached texture pointers. The next call to AssignToView will |
37 | 0 | // populate them again. |
38 | 0 | mTexture = nullptr; |
39 | 0 | mTextureOnWhite = nullptr; |
40 | 0 | return !!mHost; |
41 | 0 | } |
42 | | |
43 | | void |
44 | | PaintedLayerMLGPU::SetRenderRegion(LayerIntRegion&& aRegion) |
45 | 0 | { |
46 | 0 | mRenderRegion = std::move(aRegion); |
47 | 0 |
|
48 | 0 | LayerIntRect bounds(mRenderRegion.GetBounds().TopLeft(), |
49 | 0 | ViewAs<LayerPixel>(mTexture->GetSize())); |
50 | 0 | mRenderRegion.AndWith(bounds); |
51 | 0 | } |
52 | | |
53 | | const LayerIntRegion& |
54 | | PaintedLayerMLGPU::GetDrawRects() |
55 | 0 | { |
56 | 0 | #ifndef MOZ_IGNORE_PAINT_WILL_RESAMPLE |
57 | 0 | // Note: we don't set PaintWillResample on our ContentTextureHost. The old |
58 | 0 | // compositor must do this since ContentHost is responsible for issuing |
59 | 0 | // draw calls, but in AL we can handle it directly here. |
60 | 0 | // |
61 | 0 | // Note that when AL performs CPU-based occlusion culling (the default |
62 | 0 | // behavior), we might break up the visible region again. If that turns |
63 | 0 | // out to be a problem, we can factor this into ForEachDrawRect instead. |
64 | 0 | if (MayResample()) { |
65 | 0 | mDrawRects = mRenderRegion.GetBounds(); |
66 | 0 | return mDrawRects; |
67 | 0 | } |
68 | 0 | #endif |
69 | 0 | return mRenderRegion; |
70 | 0 | } |
71 | | |
72 | | bool |
73 | | PaintedLayerMLGPU::SetCompositableHost(CompositableHost* aHost) |
74 | 0 | { |
75 | 0 | switch (aHost->GetType()) { |
76 | 0 | case CompositableType::CONTENT_TILED: |
77 | 0 | case CompositableType::CONTENT_SINGLE: |
78 | 0 | case CompositableType::CONTENT_DOUBLE: |
79 | 0 | mHost = aHost->AsContentHost(); |
80 | 0 | if (!mHost) { |
81 | 0 | gfxWarning() << "ContentHostBase is not a ContentHostTexture"; |
82 | 0 | } |
83 | 0 | return true; |
84 | 0 | default: |
85 | 0 | return false; |
86 | 0 | } |
87 | 0 | } |
88 | | |
89 | | CompositableHost* |
90 | | PaintedLayerMLGPU::GetCompositableHost() |
91 | 0 | { |
92 | 0 | return mHost; |
93 | 0 | } |
94 | | |
95 | | gfx::Point |
96 | | PaintedLayerMLGPU::GetDestOrigin() const |
97 | 0 | { |
98 | 0 | return mDestOrigin; |
99 | 0 | } |
100 | | |
101 | | void |
102 | | PaintedLayerMLGPU::AssignToView(FrameBuilder* aBuilder, |
103 | | RenderViewMLGPU* aView, |
104 | | Maybe<Polygon>&& aGeometry) |
105 | 0 | { |
106 | 0 | if (TiledContentHost* tiles = mHost->AsTiledContentHost()) { |
107 | 0 | // Note: we do not support the low-res buffer yet. |
108 | 0 | MOZ_ASSERT(tiles->GetLowResBuffer().GetTileCount() == 0); |
109 | 0 | AssignHighResTilesToView(aBuilder, aView, tiles, aGeometry); |
110 | 0 | return; |
111 | 0 | } |
112 | 0 |
|
113 | 0 | // If we don't have a texture yet, acquire one from the ContentHost now. |
114 | 0 | if (!mTexture) { |
115 | 0 | ContentHostTexture* single = mHost->AsContentHostTexture(); |
116 | 0 | if (!single) { |
117 | 0 | return; |
118 | 0 | } |
119 | 0 | |
120 | 0 | mTexture = single->AcquireTextureSource(); |
121 | 0 | if (!mTexture) { |
122 | 0 | return; |
123 | 0 | } |
124 | 0 | mTextureOnWhite = single->AcquireTextureSourceOnWhite(); |
125 | 0 | mDestOrigin = single->GetOriginOffset(); |
126 | 0 | } |
127 | 0 |
|
128 | 0 | // Fall through to the single texture case. |
129 | 0 | LayerMLGPU::AssignToView(aBuilder, aView, std::move(aGeometry)); |
130 | 0 | } |
131 | | |
132 | | void |
133 | | PaintedLayerMLGPU::AssignHighResTilesToView(FrameBuilder* aBuilder, |
134 | | RenderViewMLGPU* aView, |
135 | | TiledContentHost* aTileHost, |
136 | | const Maybe<Polygon>& aGeometry) |
137 | 0 | { |
138 | 0 | TiledLayerBufferComposite& tiles = aTileHost->GetHighResBuffer(); |
139 | 0 |
|
140 | 0 | LayerIntRegion compositeRegion = ViewAs<LayerPixel>(tiles.GetValidRegion()); |
141 | 0 | compositeRegion.AndWith(GetShadowVisibleRegion()); |
142 | 0 | if (compositeRegion.IsEmpty()) { |
143 | 0 | return; |
144 | 0 | } |
145 | 0 | |
146 | 0 | AssignTileBufferToView(aBuilder, aView, tiles, compositeRegion, aGeometry); |
147 | 0 | } |
148 | | |
149 | | void |
150 | | PaintedLayerMLGPU::AssignTileBufferToView(FrameBuilder* aBuilder, |
151 | | RenderViewMLGPU* aView, |
152 | | TiledLayerBufferComposite& aTiles, |
153 | | const LayerIntRegion& aCompositeRegion, |
154 | | const Maybe<Polygon>& aGeometry) |
155 | 0 | { |
156 | 0 | float resolution = aTiles.GetResolution(); |
157 | 0 |
|
158 | 0 | // Save these so they can be restored at the end. |
159 | 0 | float baseOpacity = mComputedOpacity; |
160 | 0 | LayerIntRegion visible = GetShadowVisibleRegion(); |
161 | 0 |
|
162 | 0 | for (size_t i = 0; i < aTiles.GetTileCount(); i++) { |
163 | 0 | TileHost& tile = aTiles.GetTile(i); |
164 | 0 | if (tile.IsPlaceholderTile()) { |
165 | 0 | continue; |
166 | 0 | } |
167 | 0 | |
168 | 0 | TileCoordIntPoint coord = aTiles.GetPlacement().TileCoord(i); |
169 | 0 | // A sanity check that catches a lot of mistakes. |
170 | 0 | MOZ_ASSERT(coord.x == tile.mTileCoord.x && coord.y == tile.mTileCoord.y); |
171 | 0 |
|
172 | 0 | IntPoint offset = aTiles.GetTileOffset(coord); |
173 | 0 |
|
174 | 0 | // Use LayerIntRect here so we don't have to keep re-allocating the region |
175 | 0 | // to change the unit type. |
176 | 0 | LayerIntRect tileRect(ViewAs<LayerPixel>(offset), |
177 | 0 | ViewAs<LayerPixel>(aTiles.GetScaledTileSize())); |
178 | 0 | LayerIntRegion tileDrawRegion = tileRect; |
179 | 0 | tileDrawRegion.AndWith(aCompositeRegion); |
180 | 0 | if (tileDrawRegion.IsEmpty()) { |
181 | 0 | continue; |
182 | 0 | } |
183 | 0 | tileDrawRegion.ScaleRoundOut(resolution, resolution); |
184 | 0 |
|
185 | 0 | // Update layer state for this tile - that includes the texture, visible |
186 | 0 | // region, and opacity. |
187 | 0 | mTexture = tile.AcquireTextureSource(); |
188 | 0 | if (!mTexture) { |
189 | 0 | continue; |
190 | 0 | } |
191 | 0 | |
192 | 0 | mTextureOnWhite = tile.AcquireTextureSourceOnWhite(); |
193 | 0 |
|
194 | 0 | SetShadowVisibleRegion(tileDrawRegion); |
195 | 0 | mComputedOpacity = tile.GetFadeInOpacity(baseOpacity); |
196 | 0 | mDestOrigin = offset; |
197 | 0 |
|
198 | 0 | // Yes, it's a bit weird that we're assigning the same layer to the same |
199 | 0 | // view multiple times. Note that each time, the texture, computed |
200 | 0 | // opacity, origin, and visible region are updated to match the current |
201 | 0 | // tile, and we restore these properties after we've finished processing |
202 | 0 | // all tiles. |
203 | 0 | Maybe<Polygon> geometry = aGeometry; |
204 | 0 | LayerMLGPU::AssignToView(aBuilder, aView, std::move(geometry)); |
205 | 0 | } |
206 | 0 |
|
207 | 0 | // Restore the computed opacity and visible region. |
208 | 0 | mComputedOpacity = baseOpacity; |
209 | 0 | SetShadowVisibleRegion(std::move(visible)); |
210 | 0 | } |
211 | | |
212 | | void |
213 | | PaintedLayerMLGPU::CleanupResources() |
214 | 0 | { |
215 | 0 | if (mHost) { |
216 | 0 | mHost->Detach(this); |
217 | 0 | } |
218 | 0 | mTexture = nullptr; |
219 | 0 | mTextureOnWhite = nullptr; |
220 | 0 | mHost = nullptr; |
221 | 0 | } |
222 | | |
223 | | void |
224 | | PaintedLayerMLGPU::PrintInfo(std::stringstream& aStream, const char* aPrefix) |
225 | 0 | { |
226 | 0 | PaintedLayer::PrintInfo(aStream, aPrefix); |
227 | 0 | if (mHost && mHost->IsAttached()) { |
228 | 0 | aStream << "\n"; |
229 | 0 | nsAutoCString pfx(aPrefix); |
230 | 0 | pfx += " "; |
231 | 0 | mHost->PrintInfo(aStream, pfx.get()); |
232 | 0 | } |
233 | 0 | } |
234 | | |
235 | | void |
236 | | PaintedLayerMLGPU::Disconnect() |
237 | 0 | { |
238 | 0 | CleanupResources(); |
239 | 0 | } |
240 | | |
241 | | bool |
242 | | PaintedLayerMLGPU::IsContentOpaque() |
243 | 0 | { |
244 | 0 | return !!(GetContentFlags() & CONTENT_OPAQUE); |
245 | 0 | } |
246 | | |
247 | | void |
248 | | PaintedLayerMLGPU::CleanupCachedResources() |
249 | 0 | { |
250 | 0 | CleanupResources(); |
251 | 0 | } |
252 | | |
253 | | } // namespace layers |
254 | | } // namespace mozilla |