Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
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/. */
6 #include "LayerManagerD3D9.h"
8 #include "ThebesLayerD3D9.h"
9 #include "ContainerLayerD3D9.h"
10 #include "ImageLayerD3D9.h"
11 #include "ColorLayerD3D9.h"
12 #include "CanvasLayerD3D9.h"
13 #include "ReadbackLayerD3D9.h"
14 #include "gfxWindowsPlatform.h"
15 #include "nsIGfxInfo.h"
16 #include "nsServiceManagerUtils.h"
17 #include "gfxFailure.h"
18 #include "gfxPrefs.h"
20 #include "gfxCrashReporterUtils.h"
22 namespace mozilla {
23 namespace layers {
25 LayerManagerD3D9::LayerManagerD3D9(nsIWidget *aWidget)
26 : mWidget(aWidget)
27 , mDeviceResetCount(0)
28 {
29 mCurrentCallbackInfo.Callback = nullptr;
30 mCurrentCallbackInfo.CallbackData = nullptr;
31 }
33 LayerManagerD3D9::~LayerManagerD3D9()
34 {
35 Destroy();
36 }
38 bool
39 LayerManagerD3D9::Initialize(bool force)
40 {
41 ScopedGfxFeatureReporter reporter("D3D9 Layers", force);
43 /* XXX: this preference and blacklist code should move out of the layer manager */
44 bool forceAccelerate = gfxPrefs::LayersAccelerationForceEnabled();
46 nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
47 if (gfxInfo) {
48 int32_t status;
49 if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS, &status))) {
50 if (status != nsIGfxInfo::FEATURE_NO_INFO && !forceAccelerate)
51 {
52 NS_WARNING("Direct3D 9-accelerated layers are not supported on this system.");
53 return false;
54 }
55 }
56 }
58 mDeviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
59 if (!mDeviceManager) {
60 return false;
61 }
63 mSwapChain = mDeviceManager->
64 CreateSwapChain((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW));
66 if (!mSwapChain) {
67 return false;
68 }
70 reporter.SetSuccessful();
71 return true;
72 }
74 void
75 LayerManagerD3D9::SetClippingRegion(const nsIntRegion &aClippingRegion)
76 {
77 mClippingRegion = aClippingRegion;
78 }
80 void
81 LayerManagerD3D9::Destroy()
82 {
83 if (!IsDestroyed()) {
84 if (mRoot) {
85 static_cast<LayerD3D9*>(mRoot->ImplData())->LayerManagerDestroyed();
86 }
87 /* Important to release this first since it also holds a reference to the
88 * device manager
89 */
90 mSwapChain = nullptr;
91 mDeviceManager = nullptr;
92 }
93 LayerManager::Destroy();
94 }
96 void
97 LayerManagerD3D9::BeginTransaction()
98 {
99 mInTransaction = true;
100 }
102 void
103 LayerManagerD3D9::BeginTransactionWithTarget(gfxContext *aTarget)
104 {
105 mInTransaction = true;
106 mTarget = aTarget;
107 }
109 void
110 LayerManagerD3D9::EndConstruction()
111 {
112 }
114 bool
115 LayerManagerD3D9::EndEmptyTransaction(EndTransactionFlags aFlags)
116 {
117 mInTransaction = false;
119 // If the device reset count from our last EndTransaction doesn't match
120 // the current device reset count, the device must have been reset one or
121 // more times since our last transaction. In that case, an empty transaction
122 // is not possible, because layers may need to be rerendered.
123 if (!mRoot || mDeviceResetCount != mDeviceManager->GetDeviceResetCount())
124 return false;
126 EndTransaction(nullptr, nullptr, aFlags);
127 return true;
128 }
130 void
131 LayerManagerD3D9::EndTransaction(DrawThebesLayerCallback aCallback,
132 void* aCallbackData,
133 EndTransactionFlags aFlags)
134 {
135 mInTransaction = false;
137 mDeviceResetCount = mDeviceManager->GetDeviceResetCount();
139 if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) {
140 mCurrentCallbackInfo.Callback = aCallback;
141 mCurrentCallbackInfo.CallbackData = aCallbackData;
143 if (aFlags & END_NO_COMPOSITE) {
144 // Apply pending tree updates before recomputing effective
145 // properties.
146 mRoot->ApplyPendingUpdatesToSubtree();
147 }
149 // The results of our drawing always go directly into a pixel buffer,
150 // so we don't need to pass any global transform here.
151 mRoot->ComputeEffectiveTransforms(gfx::Matrix4x4());
153 SetCompositingDisabled(aFlags & END_NO_COMPOSITE);
154 Render();
155 /* Clean this out for sanity */
156 mCurrentCallbackInfo.Callback = nullptr;
157 mCurrentCallbackInfo.CallbackData = nullptr;
158 }
160 // Clear mTarget, next transaction could have no target
161 mTarget = nullptr;
162 }
164 void
165 LayerManagerD3D9::SetRoot(Layer *aLayer)
166 {
167 mRoot = aLayer;
168 }
170 already_AddRefed<ThebesLayer>
171 LayerManagerD3D9::CreateThebesLayer()
172 {
173 nsRefPtr<ThebesLayer> layer = new ThebesLayerD3D9(this);
174 return layer.forget();
175 }
177 already_AddRefed<ContainerLayer>
178 LayerManagerD3D9::CreateContainerLayer()
179 {
180 nsRefPtr<ContainerLayer> layer = new ContainerLayerD3D9(this);
181 return layer.forget();
182 }
184 already_AddRefed<ImageLayer>
185 LayerManagerD3D9::CreateImageLayer()
186 {
187 nsRefPtr<ImageLayer> layer = new ImageLayerD3D9(this);
188 return layer.forget();
189 }
191 already_AddRefed<ColorLayer>
192 LayerManagerD3D9::CreateColorLayer()
193 {
194 nsRefPtr<ColorLayer> layer = new ColorLayerD3D9(this);
195 return layer.forget();
196 }
198 already_AddRefed<CanvasLayer>
199 LayerManagerD3D9::CreateCanvasLayer()
200 {
201 nsRefPtr<CanvasLayer> layer = new CanvasLayerD3D9(this);
202 return layer.forget();
203 }
205 already_AddRefed<ReadbackLayer>
206 LayerManagerD3D9::CreateReadbackLayer()
207 {
208 nsRefPtr<ReadbackLayer> layer = new ReadbackLayerD3D9(this);
209 return layer.forget();
210 }
212 void
213 LayerManagerD3D9::ReportFailure(const nsACString &aMsg, HRESULT aCode)
214 {
215 // We could choose to abort here when hr == E_OUTOFMEMORY.
216 nsCString msg;
217 msg.Append(aMsg);
218 msg.AppendLiteral(" Error code: ");
219 msg.AppendInt(uint32_t(aCode));
220 NS_WARNING(msg.BeginReading());
222 gfx::LogFailure(msg);
223 }
225 void
226 LayerManagerD3D9::Render()
227 {
228 if (mSwapChain->PrepareForRendering() != DeviceOK) {
229 return;
230 }
232 deviceManager()->SetupRenderState();
234 SetupPipeline();
236 if (CompositingDisabled()) {
237 static_cast<LayerD3D9*>(mRoot->ImplData())->RenderLayer();
238 return;
239 }
241 nsIntRect rect;
242 mWidget->GetClientBounds(rect);
244 device()->Clear(0, nullptr, D3DCLEAR_TARGET, 0x00000000, 0, 0);
246 device()->BeginScene();
248 const nsIntRect *clipRect = mRoot->GetClipRect();
249 RECT r;
250 if (clipRect) {
251 r.left = (LONG)clipRect->x;
252 r.top = (LONG)clipRect->y;
253 r.right = (LONG)(clipRect->x + clipRect->width);
254 r.bottom = (LONG)(clipRect->y + clipRect->height);
255 } else {
256 r.left = r.top = 0;
257 r.right = rect.width;
258 r.bottom = rect.height;
259 }
260 device()->SetScissorRect(&r);
262 static_cast<LayerD3D9*>(mRoot->ImplData())->RenderLayer();
264 if (!mRegionToClear.IsEmpty()) {
265 D3DRECT* rects = new D3DRECT[mRegionToClear.GetNumRects()];
266 nsIntRegionRectIterator iter(mRegionToClear);
267 const nsIntRect *r;
268 size_t i = 0;
269 while ((r = iter.Next())) {
270 rects[i].x1 = r->x;
271 rects[i].y1 = r->y;
272 rects[i].x2 = r->x + r->width;
273 rects[i].y2 = r->y + r->height;
274 i++;
275 }
277 device()->Clear(i, rects, D3DCLEAR_TARGET,
278 0x00000000, 0, 0);
280 delete [] rects;
281 }
283 device()->EndScene();
285 if (!mTarget) {
286 const nsIntRect *r;
287 for (nsIntRegionRectIterator iter(mClippingRegion);
288 (r = iter.Next()) != nullptr;) {
289 mSwapChain->Present(*r);
290 }
291 RecordFrame();
292 PostPresent();
293 } else {
294 PaintToTarget();
295 }
296 }
298 void
299 LayerManagerD3D9::SetupPipeline()
300 {
301 nsIntRect rect;
302 mWidget->GetClientBounds(rect);
304 gfx3DMatrix viewMatrix;
305 /*
306 * Matrix to transform to viewport space ( <-1.0, 1.0> topleft,
307 * <1.0, -1.0> bottomright)
308 */
309 viewMatrix._11 = 2.0f / rect.width;
310 viewMatrix._22 = -2.0f / rect.height;
311 viewMatrix._33 = 0.0f;
312 viewMatrix._41 = -1.0f;
313 viewMatrix._42 = 1.0f;
315 HRESULT hr = device()->SetVertexShaderConstantF(CBmProjection,
316 &viewMatrix._11, 4);
318 if (FAILED(hr)) {
319 NS_WARNING("Failed to set projection shader constant!");
320 }
322 hr = device()->SetVertexShaderConstantF(CBvTextureCoords,
323 ShaderConstantRect(0, 0, 1.0f, 1.0f),
324 1);
326 if (FAILED(hr)) {
327 NS_WARNING("Failed to set texCoords shader constant!");
328 }
330 float offset[] = { 0, 0, 0, 0 };
331 hr = device()->SetVertexShaderConstantF(CBvRenderTargetOffset, offset, 1);
333 if (FAILED(hr)) {
334 NS_WARNING("Failed to set RenderTargetOffset shader constant!");
335 }
336 }
338 void
339 LayerManagerD3D9::PaintToTarget()
340 {
341 nsRefPtr<IDirect3DSurface9> backBuff;
342 nsRefPtr<IDirect3DSurface9> destSurf;
343 device()->GetRenderTarget(0, getter_AddRefs(backBuff));
345 D3DSURFACE_DESC desc;
346 backBuff->GetDesc(&desc);
348 device()->CreateOffscreenPlainSurface(desc.Width, desc.Height,
349 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
350 getter_AddRefs(destSurf), nullptr);
352 device()->GetRenderTargetData(backBuff, destSurf);
354 D3DLOCKED_RECT rect;
355 destSurf->LockRect(&rect, nullptr, D3DLOCK_READONLY);
357 nsRefPtr<gfxImageSurface> imageSurface =
358 new gfxImageSurface((unsigned char*)rect.pBits,
359 gfxIntSize(desc.Width, desc.Height),
360 rect.Pitch,
361 gfxImageFormat::ARGB32);
363 mTarget->SetSource(imageSurface);
364 mTarget->SetOperator(gfxContext::OPERATOR_OVER);
365 mTarget->Paint();
366 destSurf->UnlockRect();
367 }
369 LayerD3D9::LayerD3D9(LayerManagerD3D9 *aManager)
370 : mD3DManager(aManager)
371 {
372 }
374 } /* namespace layers */
375 } /* namespace mozilla */