| |
1 /* -*- Mode: C++; tab-width: 2; 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 #ifndef GFX_CLIENTCONTAINERLAYER_H |
| |
7 #define GFX_CLIENTCONTAINERLAYER_H |
| |
8 |
| |
9 #include <stdint.h> // for uint32_t |
| |
10 #include "ClientLayerManager.h" // for ClientLayerManager, etc |
| |
11 #include "Layers.h" // for Layer, ContainerLayer, etc |
| |
12 #include "gfxPrefs.h" // for gfxPrefs |
| |
13 #include "nsDebug.h" // for NS_ASSERTION |
| |
14 #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc |
| |
15 #include "nsISupportsUtils.h" // for NS_ADDREF, NS_RELEASE |
| |
16 #include "nsRegion.h" // for nsIntRegion |
| |
17 #include "nsTArray.h" // for nsAutoTArray |
| |
18 |
| |
19 namespace mozilla { |
| |
20 namespace layers { |
| |
21 |
| |
22 class ShadowableLayer; |
| |
23 |
| |
24 class ClientContainerLayer : public ContainerLayer, |
| |
25 public ClientLayer |
| |
26 { |
| |
27 public: |
| |
28 ClientContainerLayer(ClientLayerManager* aManager) : |
| |
29 ContainerLayer(aManager, |
| |
30 static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST())) |
| |
31 { |
| |
32 MOZ_COUNT_CTOR(ClientContainerLayer); |
| |
33 mSupportsComponentAlphaChildren = true; |
| |
34 } |
| |
35 virtual ~ClientContainerLayer() |
| |
36 { |
| |
37 while (mFirstChild) { |
| |
38 ContainerLayer::RemoveChild(mFirstChild); |
| |
39 } |
| |
40 |
| |
41 MOZ_COUNT_DTOR(ClientContainerLayer); |
| |
42 } |
| |
43 |
| |
44 virtual void RenderLayer() |
| |
45 { |
| |
46 if (GetMaskLayer()) { |
| |
47 ToClientLayer(GetMaskLayer())->RenderLayer(); |
| |
48 } |
| |
49 |
| |
50 // Setup mSupportsComponentAlphaChildren in the same way |
| |
51 // that ContainerLayerComposite will do. |
| |
52 if (UseIntermediateSurface()) { |
| |
53 if (GetEffectiveVisibleRegion().GetNumRects() != 1 || |
| |
54 !(GetContentFlags() & Layer::CONTENT_OPAQUE)) |
| |
55 { |
| |
56 gfx::Matrix transform; |
| |
57 if (HasOpaqueAncestorLayer(this) && |
| |
58 GetEffectiveTransform().Is2D(&transform) && |
| |
59 !gfx::ThebesMatrix(transform).HasNonIntegerTranslation()) { |
| |
60 SetSupportsComponentAlphaChildren( |
| |
61 gfxPrefs::ComponentAlphaEnabled()); |
| |
62 } |
| |
63 } |
| |
64 } else { |
| |
65 SetSupportsComponentAlphaChildren( |
| |
66 (GetContentFlags() & Layer::CONTENT_OPAQUE) || |
| |
67 (GetParent() && GetParent()->SupportsComponentAlphaChildren())); |
| |
68 } |
| |
69 |
| |
70 nsAutoTArray<Layer*, 12> children; |
| |
71 SortChildrenBy3DZOrder(children); |
| |
72 |
| |
73 for (uint32_t i = 0; i < children.Length(); i++) { |
| |
74 Layer* child = children.ElementAt(i); |
| |
75 if (child->GetEffectiveVisibleRegion().IsEmpty()) { |
| |
76 continue; |
| |
77 } |
| |
78 |
| |
79 ToClientLayer(child)->RenderLayer(); |
| |
80 |
| |
81 if (!ClientManager()->GetRepeatTransaction() && |
| |
82 !child->GetInvalidRegion().IsEmpty()) { |
| |
83 child->Mutated(); |
| |
84 } |
| |
85 } |
| |
86 } |
| |
87 |
| |
88 virtual void SetVisibleRegion(const nsIntRegion& aRegion) |
| |
89 { |
| |
90 NS_ASSERTION(ClientManager()->InConstruction(), |
| |
91 "Can only set properties in construction phase"); |
| |
92 ContainerLayer::SetVisibleRegion(aRegion); |
| |
93 } |
| |
94 virtual bool InsertAfter(Layer* aChild, Layer* aAfter) MOZ_OVERRIDE |
| |
95 { |
| |
96 if(!ClientManager()->InConstruction()) { |
| |
97 NS_ERROR("Can only set properties in construction phase"); |
| |
98 return false; |
| |
99 } |
| |
100 |
| |
101 if (!ContainerLayer::InsertAfter(aChild, aAfter)) { |
| |
102 return false; |
| |
103 } |
| |
104 |
| |
105 ClientManager()->AsShadowForwarder()->InsertAfter(ClientManager()->Hold(this), |
| |
106 ClientManager()->Hold(aChild), |
| |
107 aAfter ? ClientManager()->Hold(aAfter) : nullptr); |
| |
108 return true; |
| |
109 } |
| |
110 |
| |
111 virtual bool RemoveChild(Layer* aChild) MOZ_OVERRIDE |
| |
112 { |
| |
113 if (!ClientManager()->InConstruction()) { |
| |
114 NS_ERROR("Can only set properties in construction phase"); |
| |
115 return false; |
| |
116 } |
| |
117 // hold on to aChild before we remove it! |
| |
118 ShadowableLayer *heldChild = ClientManager()->Hold(aChild); |
| |
119 if (!ContainerLayer::RemoveChild(aChild)) { |
| |
120 return false; |
| |
121 } |
| |
122 ClientManager()->AsShadowForwarder()->RemoveChild(ClientManager()->Hold(this), heldChild); |
| |
123 return true; |
| |
124 } |
| |
125 |
| |
126 virtual bool RepositionChild(Layer* aChild, Layer* aAfter) MOZ_OVERRIDE |
| |
127 { |
| |
128 if (!ClientManager()->InConstruction()) { |
| |
129 NS_ERROR("Can only set properties in construction phase"); |
| |
130 return false; |
| |
131 } |
| |
132 if (!ContainerLayer::RepositionChild(aChild, aAfter)) { |
| |
133 return false; |
| |
134 } |
| |
135 ClientManager()->AsShadowForwarder()->RepositionChild(ClientManager()->Hold(this), |
| |
136 ClientManager()->Hold(aChild), |
| |
137 aAfter ? ClientManager()->Hold(aAfter) : nullptr); |
| |
138 return true; |
| |
139 } |
| |
140 |
| |
141 virtual Layer* AsLayer() { return this; } |
| |
142 virtual ShadowableLayer* AsShadowableLayer() { return this; } |
| |
143 |
| |
144 virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) |
| |
145 { |
| |
146 DefaultComputeEffectiveTransforms(aTransformToSurface); |
| |
147 } |
| |
148 |
| |
149 void ForceIntermediateSurface() { mUseIntermediateSurface = true; } |
| |
150 |
| |
151 void SetSupportsComponentAlphaChildren(bool aSupports) { mSupportsComponentAlphaChildren = aSupports; } |
| |
152 |
| |
153 protected: |
| |
154 ClientLayerManager* ClientManager() |
| |
155 { |
| |
156 return static_cast<ClientLayerManager*>(mManager); |
| |
157 } |
| |
158 }; |
| |
159 |
| |
160 class ClientRefLayer : public RefLayer, |
| |
161 public ClientLayer { |
| |
162 public: |
| |
163 ClientRefLayer(ClientLayerManager* aManager) : |
| |
164 RefLayer(aManager, |
| |
165 static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST())) |
| |
166 { |
| |
167 MOZ_COUNT_CTOR(ClientRefLayer); |
| |
168 } |
| |
169 virtual ~ClientRefLayer() |
| |
170 { |
| |
171 MOZ_COUNT_DTOR(ClientRefLayer); |
| |
172 } |
| |
173 |
| |
174 virtual Layer* AsLayer() { return this; } |
| |
175 virtual ShadowableLayer* AsShadowableLayer() { return this; } |
| |
176 |
| |
177 virtual void Disconnect() |
| |
178 { |
| |
179 ClientLayer::Disconnect(); |
| |
180 } |
| |
181 |
| |
182 virtual void RenderLayer() { } |
| |
183 |
| |
184 virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) |
| |
185 { |
| |
186 DefaultComputeEffectiveTransforms(aTransformToSurface); |
| |
187 } |
| |
188 |
| |
189 private: |
| |
190 ClientLayerManager* ClientManager() |
| |
191 { |
| |
192 return static_cast<ClientLayerManager*>(mManager); |
| |
193 } |
| |
194 }; |
| |
195 |
| |
196 } |
| |
197 } |
| |
198 |
| |
199 #endif |