|
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 #include "ClientLayerManager.h" // for ClientLayerManager, etc |
|
7 #include "ImageContainer.h" // for AutoLockImage, etc |
|
8 #include "ImageLayers.h" // for ImageLayer |
|
9 #include "mozilla/Attributes.h" // for MOZ_OVERRIDE |
|
10 #include "mozilla/RefPtr.h" // for RefPtr |
|
11 #include "mozilla/layers/CompositorTypes.h" |
|
12 #include "mozilla/layers/ImageClient.h" // for ImageClient, etc |
|
13 #include "mozilla/layers/LayersMessages.h" // for ImageLayerAttributes, etc |
|
14 #include "mozilla/mozalloc.h" // for operator delete, etc |
|
15 #include "nsAutoPtr.h" // for nsRefPtr, getter_AddRefs, etc |
|
16 #include "nsCOMPtr.h" // for already_AddRefed |
|
17 #include "nsDebug.h" // for NS_ASSERTION |
|
18 #include "nsISupportsImpl.h" // for Layer::AddRef, etc |
|
19 #include "nsRegion.h" // for nsIntRegion |
|
20 |
|
21 using namespace mozilla::gfx; |
|
22 |
|
23 namespace mozilla { |
|
24 namespace layers { |
|
25 |
|
26 class ClientImageLayer : public ImageLayer, |
|
27 public ClientLayer { |
|
28 public: |
|
29 ClientImageLayer(ClientLayerManager* aLayerManager) |
|
30 : ImageLayer(aLayerManager, |
|
31 static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST())) |
|
32 , mImageClientTypeContainer(BUFFER_UNKNOWN) |
|
33 { |
|
34 MOZ_COUNT_CTOR(ClientImageLayer); |
|
35 } |
|
36 virtual ~ClientImageLayer() |
|
37 { |
|
38 DestroyBackBuffer(); |
|
39 MOZ_COUNT_DTOR(ClientImageLayer); |
|
40 } |
|
41 |
|
42 virtual void SetContainer(ImageContainer* aContainer) MOZ_OVERRIDE |
|
43 { |
|
44 ImageLayer::SetContainer(aContainer); |
|
45 mImageClientTypeContainer = BUFFER_UNKNOWN; |
|
46 } |
|
47 |
|
48 virtual void SetVisibleRegion(const nsIntRegion& aRegion) |
|
49 { |
|
50 NS_ASSERTION(ClientManager()->InConstruction(), |
|
51 "Can only set properties in construction phase"); |
|
52 ImageLayer::SetVisibleRegion(aRegion); |
|
53 } |
|
54 |
|
55 virtual void RenderLayer(); |
|
56 |
|
57 virtual void ClearCachedResources() MOZ_OVERRIDE |
|
58 { |
|
59 DestroyBackBuffer(); |
|
60 } |
|
61 |
|
62 virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) |
|
63 { |
|
64 aAttrs = ImageLayerAttributes(mFilter, mScaleToSize, mScaleMode); |
|
65 } |
|
66 |
|
67 virtual Layer* AsLayer() { return this; } |
|
68 virtual ShadowableLayer* AsShadowableLayer() { return this; } |
|
69 |
|
70 virtual void Disconnect() |
|
71 { |
|
72 DestroyBackBuffer(); |
|
73 ClientLayer::Disconnect(); |
|
74 } |
|
75 |
|
76 void DestroyBackBuffer() |
|
77 { |
|
78 if (mImageClient) { |
|
79 mImageClient->OnDetach(); |
|
80 mImageClient = nullptr; |
|
81 } |
|
82 } |
|
83 |
|
84 virtual CompositableClient* GetCompositableClient() MOZ_OVERRIDE |
|
85 { |
|
86 return mImageClient; |
|
87 } |
|
88 |
|
89 protected: |
|
90 ClientLayerManager* ClientManager() |
|
91 { |
|
92 return static_cast<ClientLayerManager*>(mManager); |
|
93 } |
|
94 |
|
95 CompositableType GetImageClientType() |
|
96 { |
|
97 if (mImageClientTypeContainer != BUFFER_UNKNOWN) { |
|
98 return mImageClientTypeContainer; |
|
99 } |
|
100 |
|
101 if (mContainer->IsAsync()) { |
|
102 mImageClientTypeContainer = BUFFER_BRIDGE; |
|
103 return mImageClientTypeContainer; |
|
104 } |
|
105 |
|
106 RefPtr<gfx::SourceSurface> surface; |
|
107 AutoLockImage autoLock(mContainer, &surface); |
|
108 |
|
109 #ifdef MOZ_WIDGET_GONK |
|
110 // gralloc buffer needs BUFFER_IMAGE_BUFFERED to prevent |
|
111 // the buffer's usage conflict. |
|
112 mImageClientTypeContainer = autoLock.GetImage() ? |
|
113 BUFFER_IMAGE_BUFFERED : BUFFER_UNKNOWN; |
|
114 #else |
|
115 mImageClientTypeContainer = autoLock.GetImage() ? |
|
116 BUFFER_IMAGE_SINGLE : BUFFER_UNKNOWN; |
|
117 #endif |
|
118 return mImageClientTypeContainer; |
|
119 } |
|
120 |
|
121 RefPtr<ImageClient> mImageClient; |
|
122 CompositableType mImageClientTypeContainer; |
|
123 }; |
|
124 |
|
125 void |
|
126 ClientImageLayer::RenderLayer() |
|
127 { |
|
128 if (GetMaskLayer()) { |
|
129 ToClientLayer(GetMaskLayer())->RenderLayer(); |
|
130 } |
|
131 |
|
132 if (!mContainer) { |
|
133 return; |
|
134 } |
|
135 |
|
136 if (mImageClient) { |
|
137 mImageClient->OnTransaction(); |
|
138 } |
|
139 |
|
140 if (!mImageClient || |
|
141 !mImageClient->UpdateImage(mContainer, GetContentFlags())) { |
|
142 CompositableType type = GetImageClientType(); |
|
143 if (type == BUFFER_UNKNOWN) { |
|
144 return; |
|
145 } |
|
146 TextureFlags flags = TEXTURE_FRONT; |
|
147 if (mDisallowBigImage) { |
|
148 flags |= TEXTURE_DISALLOW_BIGIMAGE; |
|
149 } |
|
150 mImageClient = ImageClient::CreateImageClient(type, |
|
151 ClientManager()->AsShadowForwarder(), |
|
152 flags); |
|
153 if (type == BUFFER_BRIDGE) { |
|
154 static_cast<ImageClientBridge*>(mImageClient.get())->SetLayer(this); |
|
155 } |
|
156 |
|
157 if (!mImageClient) { |
|
158 return; |
|
159 } |
|
160 if (HasShadow() && !mContainer->IsAsync()) { |
|
161 mImageClient->Connect(); |
|
162 ClientManager()->AsShadowForwarder()->Attach(mImageClient, this); |
|
163 } |
|
164 if (!mImageClient->UpdateImage(mContainer, GetContentFlags())) { |
|
165 return; |
|
166 } |
|
167 } |
|
168 if (mImageClient) { |
|
169 mImageClient->OnTransaction(); |
|
170 } |
|
171 ClientManager()->Hold(this); |
|
172 } |
|
173 |
|
174 already_AddRefed<ImageLayer> |
|
175 ClientLayerManager::CreateImageLayer() |
|
176 { |
|
177 NS_ASSERTION(InConstruction(), "Only allowed in construction phase"); |
|
178 nsRefPtr<ClientImageLayer> layer = |
|
179 new ClientImageLayer(this); |
|
180 CREATE_SHADOW(Image); |
|
181 return layer.forget(); |
|
182 } |
|
183 } |
|
184 } |