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 "TextureD3D11.h"
7 #include "CompositorD3D11.h"
8 #include "gfxContext.h"
9 #include "Effects.h"
10 #include "mozilla/layers/YCbCrImageDataSerializer.h"
11 #include "gfxWindowsPlatform.h"
12 #include "gfxD2DSurface.h"
13 #include "gfx2DGlue.h"
15 namespace mozilla {
17 using namespace gfx;
19 namespace layers {
21 static DXGI_FORMAT
22 SurfaceFormatToDXGIFormat(gfx::SurfaceFormat aFormat)
23 {
24 switch (aFormat) {
25 case SurfaceFormat::B8G8R8A8:
26 return DXGI_FORMAT_B8G8R8A8_UNORM;
27 case SurfaceFormat::B8G8R8X8:
28 return DXGI_FORMAT_B8G8R8A8_UNORM;
29 case SurfaceFormat::A8:
30 return DXGI_FORMAT_A8_UNORM;
31 default:
32 MOZ_ASSERT(false, "unsupported format");
33 return DXGI_FORMAT_UNKNOWN;
34 }
35 }
37 static uint32_t
38 GetRequiredTilesD3D11(uint32_t aSize, uint32_t aMaxSize)
39 {
40 uint32_t requiredTiles = aSize / aMaxSize;
41 if (aSize % aMaxSize) {
42 requiredTiles++;
43 }
44 return requiredTiles;
45 }
47 static IntRect
48 GetTileRectD3D11(uint32_t aID, IntSize aSize, uint32_t aMaxSize)
49 {
50 uint32_t horizontalTiles = GetRequiredTilesD3D11(aSize.width, aMaxSize);
51 uint32_t verticalTiles = GetRequiredTilesD3D11(aSize.height, aMaxSize);
53 uint32_t verticalTile = aID / horizontalTiles;
54 uint32_t horizontalTile = aID % horizontalTiles;
56 return IntRect(horizontalTile * aMaxSize,
57 verticalTile * aMaxSize,
58 horizontalTile < (horizontalTiles - 1) ? aMaxSize : aSize.width % aMaxSize,
59 verticalTile < (verticalTiles - 1) ? aMaxSize : aSize.height % aMaxSize);
60 }
62 DataTextureSourceD3D11::DataTextureSourceD3D11(SurfaceFormat aFormat,
63 CompositorD3D11* aCompositor,
64 TextureFlags aFlags)
65 : mCompositor(aCompositor)
66 , mFormat(aFormat)
67 , mFlags(aFlags)
68 , mCurrentTile(0)
69 , mIsTiled(false)
70 , mIterating(false)
71 {
72 MOZ_COUNT_CTOR(DataTextureSourceD3D11);
73 }
75 DataTextureSourceD3D11::DataTextureSourceD3D11(SurfaceFormat aFormat,
76 CompositorD3D11* aCompositor,
77 ID3D11Texture2D* aTexture)
78 : mCompositor(aCompositor)
79 , mFormat(aFormat)
80 , mFlags(0)
81 , mCurrentTile(0)
82 , mIsTiled(false)
83 , mIterating(false)
84 {
85 MOZ_COUNT_CTOR(DataTextureSourceD3D11);
87 mTexture = aTexture;
88 D3D11_TEXTURE2D_DESC desc;
89 aTexture->GetDesc(&desc);
91 mSize = IntSize(desc.Width, desc.Height);
92 }
96 DataTextureSourceD3D11::~DataTextureSourceD3D11()
97 {
98 MOZ_COUNT_DTOR(DataTextureSourceD3D11);
99 }
102 template<typename T> // ID3D10Texture2D or ID3D11Texture2D
103 static void LockD3DTexture(T* aTexture)
104 {
105 MOZ_ASSERT(aTexture);
106 RefPtr<IDXGIKeyedMutex> mutex;
107 aTexture->QueryInterface((IDXGIKeyedMutex**)byRef(mutex));
108 if (mutex) {
109 mutex->AcquireSync(0, INFINITE);
110 }
111 }
113 template<typename T> // ID3D10Texture2D or ID3D11Texture2D
114 static void UnlockD3DTexture(T* aTexture)
115 {
116 MOZ_ASSERT(aTexture);
117 RefPtr<IDXGIKeyedMutex> mutex;
118 aTexture->QueryInterface((IDXGIKeyedMutex**)byRef(mutex));
119 if (mutex) {
120 mutex->ReleaseSync(0);
121 }
122 }
124 TemporaryRef<TextureHost>
125 CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
126 ISurfaceAllocator* aDeallocator,
127 TextureFlags aFlags)
128 {
129 RefPtr<TextureHost> result;
130 switch (aDesc.type()) {
131 case SurfaceDescriptor::TSurfaceDescriptorShmem:
132 case SurfaceDescriptor::TSurfaceDescriptorMemory: {
133 result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
134 break;
135 }
136 case SurfaceDescriptor::TSurfaceDescriptorD3D10: {
137 result = new DXGITextureHostD3D11(aFlags,
138 aDesc.get_SurfaceDescriptorD3D10());
139 break;
140 }
141 default: {
142 NS_WARNING("Unsupported SurfaceDescriptor type");
143 }
144 }
145 return result;
146 }
148 TextureClientD3D11::TextureClientD3D11(gfx::SurfaceFormat aFormat, TextureFlags aFlags)
149 : TextureClient(aFlags)
150 , mFormat(aFormat)
151 , mIsLocked(false)
152 , mNeedsClear(false)
153 {}
155 TextureClientD3D11::~TextureClientD3D11()
156 {
157 #ifdef DEBUG
158 // An Azure DrawTarget needs to be locked when it gets nullptr'ed as this is
159 // when it calls EndDraw. This EndDraw should not execute anything so it
160 // shouldn't -really- need the lock but the debug layer chokes on this.
161 if (mDrawTarget) {
162 MOZ_ASSERT(!mIsLocked);
163 MOZ_ASSERT(mTexture);
164 MOZ_ASSERT(mDrawTarget->refCount() == 1);
165 LockD3DTexture(mTexture.get());
166 mDrawTarget = nullptr;
167 UnlockD3DTexture(mTexture.get());
168 }
169 #endif
170 }
172 bool
173 TextureClientD3D11::Lock(OpenMode aMode)
174 {
175 if (!mTexture) {
176 return false;
177 }
178 MOZ_ASSERT(!mIsLocked, "The Texture is already locked!");
179 LockD3DTexture(mTexture.get());
180 mIsLocked = true;
182 if (mNeedsClear) {
183 mDrawTarget = GetAsDrawTarget();
184 mDrawTarget->ClearRect(Rect(0, 0, GetSize().width, GetSize().height));
185 mNeedsClear = false;
186 }
188 return true;
189 }
191 void
192 TextureClientD3D11::Unlock()
193 {
194 MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!");
196 if (mDrawTarget) {
197 // see the comment on TextureClient::GetAsDrawTarget.
198 // This DrawTarget is internal to the TextureClient and is only exposed to the
199 // outside world between Lock() and Unlock(). This assertion checks that no outside
200 // reference remains by the time Unlock() is called.
201 MOZ_ASSERT(mDrawTarget->refCount() == 1);
202 mDrawTarget->Flush();
203 }
205 // The DrawTarget is created only once, and is only usable between calls
206 // to Lock and Unlock.
207 UnlockD3DTexture(mTexture.get());
208 mIsLocked = false;
209 }
211 TemporaryRef<DrawTarget>
212 TextureClientD3D11::GetAsDrawTarget()
213 {
214 MOZ_ASSERT(mIsLocked, "Calling TextureClient::GetAsDrawTarget without locking :(");
216 if (!mTexture) {
217 return nullptr;
218 }
220 if (mDrawTarget) {
221 return mDrawTarget;
222 }
224 mDrawTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture, mFormat);
225 return mDrawTarget;
226 }
228 bool
229 TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
230 {
231 mSize = aSize;
232 ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
234 CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
235 aSize.width, aSize.height, 1, 1,
236 D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE);
238 newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;
240 HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture));
242 if (FAILED(hr)) {
243 LOGD3D11("Error creating texture for client!");
244 return false;
245 }
247 // Defer clearing to the next time we lock to avoid an extra (expensive) lock.
248 mNeedsClear = aFlags & ALLOC_CLEAR_BUFFER;
250 return true;
251 }
253 bool
254 TextureClientD3D11::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
255 {
256 if (!IsAllocated()) {
257 return false;
258 }
260 RefPtr<IDXGIResource> resource;
261 mTexture->QueryInterface((IDXGIResource**)byRef(resource));
262 HANDLE sharedHandle;
263 HRESULT hr = resource->GetSharedHandle(&sharedHandle);
265 if (FAILED(hr)) {
266 LOGD3D11("Error getting shared handle for texture.");
267 return false;
268 }
270 aOutDescriptor = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, mFormat, mSize);
271 return true;
272 }
274 DXGITextureHostD3D11::DXGITextureHostD3D11(TextureFlags aFlags,
275 const SurfaceDescriptorD3D10& aDescriptor)
276 : TextureHost(aFlags)
277 , mHandle(aDescriptor.handle())
278 , mFormat(aDescriptor.format())
279 , mIsLocked(false)
280 {}
282 ID3D11Device*
283 DXGITextureHostD3D11::GetDevice()
284 {
285 return mCompositor ? mCompositor->GetDevice() : nullptr;
286 }
288 void
289 DXGITextureHostD3D11::SetCompositor(Compositor* aCompositor)
290 {
291 mCompositor = static_cast<CompositorD3D11*>(aCompositor);
292 }
294 bool
295 DXGITextureHostD3D11::Lock()
296 {
297 if (!GetDevice()) {
298 NS_WARNING("trying to lock a TextureHost without a D3D device");
299 return false;
300 }
301 if (!mTextureSource) {
302 RefPtr<ID3D11Texture2D> tex;
303 HRESULT hr = GetDevice()->OpenSharedResource((HANDLE)mHandle,
304 __uuidof(ID3D11Texture2D),
305 (void**)(ID3D11Texture2D**)byRef(tex));
306 if (FAILED(hr)) {
307 NS_WARNING("Failed to open shared texture");
308 return false;
309 }
311 mTextureSource = new DataTextureSourceD3D11(mFormat, mCompositor, tex);
312 D3D11_TEXTURE2D_DESC desc;
313 tex->GetDesc(&desc);
314 mSize = IntSize(desc.Width, desc.Height);
315 }
317 LockD3DTexture(mTextureSource->GetD3D11Texture());
319 mIsLocked = true;
320 return true;
321 }
323 void
324 DXGITextureHostD3D11::Unlock()
325 {
326 MOZ_ASSERT(mIsLocked);
327 UnlockD3DTexture(mTextureSource->GetD3D11Texture());
328 mIsLocked = false;
329 }
331 NewTextureSource*
332 DXGITextureHostD3D11::GetTextureSources()
333 {
334 return mTextureSource.get();
335 }
337 bool
338 DataTextureSourceD3D11::Update(DataSourceSurface* aSurface,
339 nsIntRegion* aDestRegion,
340 IntPoint* aSrcOffset)
341 {
342 // Right now we only support full surface update. If aDestRegion is provided,
343 // It will be ignored. Incremental update with a source offset is only used
344 // on Mac so it is not clear that we ever will need to support it for D3D.
345 MOZ_ASSERT(!aSrcOffset);
346 MOZ_ASSERT(aSurface);
348 if (!mCompositor || !mCompositor->GetDevice()) {
349 return false;
350 }
352 uint32_t bpp = BytesPerPixel(aSurface->GetFormat());
353 DXGI_FORMAT dxgiFormat = SurfaceFormatToDXGIFormat(aSurface->GetFormat());
355 mSize = aSurface->GetSize();
356 mFormat = aSurface->GetFormat();
358 CD3D11_TEXTURE2D_DESC desc(dxgiFormat, mSize.width, mSize.height,
359 1, 1, D3D11_BIND_SHADER_RESOURCE,
360 D3D11_USAGE_IMMUTABLE);
362 int32_t maxSize = mCompositor->GetMaxTextureSize();
363 if ((mSize.width <= maxSize && mSize.height <= maxSize) ||
364 (mFlags & TEXTURE_DISALLOW_BIGIMAGE)) {
365 D3D11_SUBRESOURCE_DATA initData;
366 initData.pSysMem = aSurface->GetData();
367 initData.SysMemPitch = aSurface->Stride();
369 mCompositor->GetDevice()->CreateTexture2D(&desc, &initData, byRef(mTexture));
370 mIsTiled = false;
371 if (!mTexture) {
372 Reset();
373 return false;
374 }
375 } else {
376 mIsTiled = true;
377 uint32_t tileCount = GetRequiredTilesD3D11(mSize.width, maxSize) *
378 GetRequiredTilesD3D11(mSize.height, maxSize);
380 mTileTextures.resize(tileCount);
381 mTexture = nullptr;
383 for (uint32_t i = 0; i < tileCount; i++) {
384 IntRect tileRect = GetTileRect(i);
386 desc.Width = tileRect.width;
387 desc.Height = tileRect.height;
389 D3D11_SUBRESOURCE_DATA initData;
390 initData.pSysMem = aSurface->GetData() +
391 tileRect.y * aSurface->Stride() +
392 tileRect.x * bpp;
393 initData.SysMemPitch = aSurface->Stride();
395 mCompositor->GetDevice()->CreateTexture2D(&desc, &initData, byRef(mTileTextures[i]));
396 if (!mTileTextures[i]) {
397 Reset();
398 return false;
399 }
400 }
401 }
402 return true;
403 }
405 ID3D11Texture2D*
406 DataTextureSourceD3D11::GetD3D11Texture() const
407 {
408 return mIterating ? mTileTextures[mCurrentTile]
409 : mTexture;
410 }
412 void
413 DataTextureSourceD3D11::Reset()
414 {
415 mTexture = nullptr;
416 mTileTextures.resize(0);
417 mIsTiled = false;
418 mSize.width = 0;
419 mSize.height = 0;
420 }
422 IntRect
423 DataTextureSourceD3D11::GetTileRect(uint32_t aIndex) const
424 {
425 return GetTileRectD3D11(aIndex, mSize, mCompositor->GetMaxTextureSize());
426 }
428 nsIntRect
429 DataTextureSourceD3D11::GetTileRect()
430 {
431 IntRect rect = GetTileRect(mCurrentTile);
432 return nsIntRect(rect.x, rect.y, rect.width, rect.height);
433 }
435 void
436 DataTextureSourceD3D11::SetCompositor(Compositor* aCompositor)
437 {
438 CompositorD3D11* d3dCompositor = static_cast<CompositorD3D11*>(aCompositor);
439 if (mCompositor && mCompositor != d3dCompositor) {
440 Reset();
441 }
442 mCompositor = d3dCompositor;
443 }
445 CompositingRenderTargetD3D11::CompositingRenderTargetD3D11(ID3D11Texture2D* aTexture,
446 const gfx::IntPoint& aOrigin)
447 : CompositingRenderTarget(aOrigin)
448 {
449 MOZ_ASSERT(aTexture);
451 mTexture = aTexture;
453 RefPtr<ID3D11Device> device;
454 mTexture->GetDevice(byRef(device));
456 HRESULT hr = device->CreateRenderTargetView(mTexture, nullptr, byRef(mRTView));
458 if (FAILED(hr)) {
459 LOGD3D11("Failed to create RenderTargetView.");
460 }
461 }
463 IntSize
464 CompositingRenderTargetD3D11::GetSize() const
465 {
466 return TextureSourceD3D11::GetSize();
467 }
469 }
470 }