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 "TextureD3D9.h"
7 #include "CompositorD3D9.h"
8 #include "gfxContext.h"
9 #include "gfxImageSurface.h"
10 #include "Effects.h"
11 #include "mozilla/layers/YCbCrImageDataSerializer.h"
12 #include "gfxWindowsPlatform.h"
13 #include "gfx2DGlue.h"
14 #include "gfxUtils.h"
15 #include "mozilla/gfx/2D.h"
17 using namespace mozilla::gfx;
19 namespace mozilla {
20 namespace layers {
22 static uint32_t GetRequiredTilesD3D9(uint32_t aSize, uint32_t aMaxSize)
23 {
24 uint32_t requiredTiles = aSize / aMaxSize;
25 if (aSize % aMaxSize) {
26 requiredTiles++;
27 }
28 return requiredTiles;
29 }
31 TextureSourceD3D9::~TextureSourceD3D9()
32 {
33 MOZ_ASSERT(!mCreatingDeviceManager ||
34 mCreatingDeviceManager->IsInTextureHostList(this),
35 "Inconsistency in list of texture hosts.");
36 // Remove ourselves from the list of d3d9 texture hosts.
37 if (mPreviousHost) {
38 MOZ_ASSERT(mPreviousHost->mNextHost == this);
39 mPreviousHost->mNextHost = mNextHost;
40 } else if (mCreatingDeviceManager) {
41 mCreatingDeviceManager->RemoveTextureListHead(this);
42 }
43 if (mNextHost) {
44 MOZ_ASSERT(mNextHost->mPreviousHost == this);
45 mNextHost->mPreviousHost = mPreviousHost;
46 }
47 }
49 TemporaryRef<TextureHost>
50 CreateTextureHostD3D9(const SurfaceDescriptor& aDesc,
51 ISurfaceAllocator* aDeallocator,
52 TextureFlags aFlags)
53 {
54 RefPtr<TextureHost> result;
55 switch (aDesc.type()) {
56 case SurfaceDescriptor::TSurfaceDescriptorShmem:
57 case SurfaceDescriptor::TSurfaceDescriptorMemory: {
58 result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
59 break;
60 }
61 case SurfaceDescriptor::TSurfaceDescriptorD3D9: {
62 result = new TextureHostD3D9(aFlags, aDesc);
63 break;
64 }
65 case SurfaceDescriptor::TSurfaceDescriptorDIB: {
66 result = new DIBTextureHostD3D9(aFlags, aDesc);
67 break;
68 }
69 case SurfaceDescriptor::TSurfaceDescriptorD3D10: {
70 result = new DXGITextureHostD3D9(aFlags, aDesc);
71 break;
72 }
73 default: {
74 NS_WARNING("Unsupported SurfaceDescriptor type");
75 }
76 }
77 return result.forget();
78 }
80 static SurfaceFormat
81 D3D9FormatToSurfaceFormat(_D3DFORMAT format)
82 {
83 switch (format) {
84 case D3DFMT_X8R8G8B8:
85 return SurfaceFormat::B8G8R8X8;
86 case D3DFMT_A8R8G8B8:
87 return SurfaceFormat::B8G8R8A8;
88 case D3DFMT_A8:
89 return SurfaceFormat::A8;
90 default:
91 NS_ERROR("Bad texture format");
92 }
93 return SurfaceFormat::UNKNOWN;
94 }
96 static _D3DFORMAT
97 SurfaceFormatToD3D9Format(SurfaceFormat format)
98 {
99 switch (format) {
100 case SurfaceFormat::B8G8R8X8:
101 return D3DFMT_X8R8G8B8;
102 case SurfaceFormat::B8G8R8A8:
103 return D3DFMT_A8R8G8B8;
104 case SurfaceFormat::A8:
105 return D3DFMT_A8;
106 default:
107 NS_ERROR("Bad texture format");
108 }
109 return D3DFMT_A8R8G8B8;
110 }
112 CompositingRenderTargetD3D9::CompositingRenderTargetD3D9(IDirect3DTexture9* aTexture,
113 SurfaceInitMode aInit,
114 const gfx::IntRect& aRect)
115 : CompositingRenderTarget(aRect.TopLeft())
116 , mInitMode(aInit)
117 , mInitialized(false)
118 {
119 MOZ_COUNT_CTOR(CompositingRenderTargetD3D9);
120 MOZ_ASSERT(aTexture);
122 mTexture = aTexture;
123 HRESULT hr = mTexture->GetSurfaceLevel(0, getter_AddRefs(mSurface));
124 NS_ASSERTION(mSurface, "Couldn't create surface for texture");
125 TextureSourceD3D9::SetSize(aRect.Size());
126 }
128 CompositingRenderTargetD3D9::CompositingRenderTargetD3D9(IDirect3DSurface9* aSurface,
129 SurfaceInitMode aInit,
130 const gfx::IntRect& aRect)
131 : CompositingRenderTarget(aRect.TopLeft())
132 , mSurface(aSurface)
133 , mInitMode(aInit)
134 , mInitialized(false)
135 {
136 MOZ_COUNT_CTOR(CompositingRenderTargetD3D9);
137 MOZ_ASSERT(mSurface);
138 TextureSourceD3D9::SetSize(aRect.Size());
139 }
141 CompositingRenderTargetD3D9::~CompositingRenderTargetD3D9()
142 {
143 MOZ_COUNT_DTOR(CompositingRenderTargetD3D9);
144 }
146 void
147 CompositingRenderTargetD3D9::BindRenderTarget(IDirect3DDevice9* aDevice)
148 {
149 aDevice->SetRenderTarget(0, mSurface);
150 if (!mInitialized &&
151 mInitMode == INIT_MODE_CLEAR) {
152 mInitialized = true;
153 aDevice->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 0, 0);
154 }
155 }
157 IntSize
158 CompositingRenderTargetD3D9::GetSize() const
159 {
160 return TextureSourceD3D9::GetSize();
161 }
163 /**
164 * Helper method for DataToTexture and SurfaceToTexture.
165 * The last three params are out params.
166 * Returns the created texture, or null if we fail.
167 */
168 TemporaryRef<IDirect3DTexture9>
169 TextureSourceD3D9::InitTextures(DeviceManagerD3D9* aDeviceManager,
170 const IntSize &aSize,
171 _D3DFORMAT aFormat,
172 RefPtr<IDirect3DSurface9>& aSurface,
173 D3DLOCKED_RECT& aLockedRect)
174 {
175 if (!aDeviceManager) {
176 return nullptr;
177 }
178 RefPtr<IDirect3DTexture9> result;
179 // D3D9Ex doesn't support managed textures and we don't want the hassle even
180 // if we don't have Ex. We could use dynamic textures
181 // here but since Images are immutable that probably isn't such a great
182 // idea.
183 result = aDeviceManager->CreateTexture(aSize, aFormat, D3DPOOL_DEFAULT, this);
184 if (!result) {
185 return nullptr;
186 }
188 RefPtr<IDirect3DTexture9> tmpTexture =
189 aDeviceManager->CreateTexture(aSize, aFormat, D3DPOOL_SYSTEMMEM, this);
190 if (!tmpTexture) {
191 return nullptr;
192 }
194 tmpTexture->GetSurfaceLevel(0, byRef(aSurface));
195 aSurface->LockRect(&aLockedRect, nullptr, 0);
196 if (!aLockedRect.pBits) {
197 NS_WARNING("Could not lock surface");
198 return nullptr;
199 }
201 return result;
202 }
204 /**
205 * Helper method for DataToTexture and SurfaceToTexture.
206 */
207 static void
208 FinishTextures(DeviceManagerD3D9* aDeviceManager,
209 IDirect3DTexture9* aTexture,
210 IDirect3DSurface9* aSurface)
211 {
212 if (!aDeviceManager) {
213 return;
214 }
216 aSurface->UnlockRect();
217 nsRefPtr<IDirect3DSurface9> dstSurface;
218 aTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
219 aDeviceManager->device()->UpdateSurface(aSurface, nullptr, dstSurface,
220 nullptr);
221 }
223 TemporaryRef<IDirect3DTexture9>
224 TextureSourceD3D9::DataToTexture(DeviceManagerD3D9* aDeviceManager,
225 unsigned char *aData,
226 int aStride,
227 const IntSize &aSize,
228 _D3DFORMAT aFormat,
229 uint32_t aBPP)
230 {
231 RefPtr<IDirect3DSurface9> surface;
232 D3DLOCKED_RECT lockedRect;
233 RefPtr<IDirect3DTexture9> texture = InitTextures(aDeviceManager, aSize, aFormat,
234 surface, lockedRect);
235 if (!texture) {
236 return nullptr;
237 }
239 uint32_t width = aSize.width * aBPP;
241 for (int y = 0; y < aSize.height; y++) {
242 memcpy((char*)lockedRect.pBits + lockedRect.Pitch * y,
243 aData + aStride * y,
244 width);
245 }
247 FinishTextures(aDeviceManager, texture, surface);
249 return texture;
250 }
252 TemporaryRef<IDirect3DTexture9>
253 TextureSourceD3D9::TextureToTexture(DeviceManagerD3D9* aDeviceManager,
254 IDirect3DTexture9* aTexture,
255 const IntSize& aSize,
256 _D3DFORMAT aFormat)
257 {
258 if (!aDeviceManager) {
259 return nullptr;
260 }
262 RefPtr<IDirect3DTexture9> texture =
263 aDeviceManager->CreateTexture(aSize, aFormat, D3DPOOL_DEFAULT, this);
264 if (!texture) {
265 return nullptr;
266 }
268 HRESULT hr = aDeviceManager->device()->UpdateTexture(aTexture, texture);
269 if (FAILED(hr)) {
270 return nullptr;
271 }
273 return texture;
274 }
276 TemporaryRef<IDirect3DTexture9>
277 TextureSourceD3D9::SurfaceToTexture(DeviceManagerD3D9* aDeviceManager,
278 gfxWindowsSurface* aSurface,
279 const IntSize& aSize,
280 _D3DFORMAT aFormat)
281 {
282 RefPtr<IDirect3DSurface9> surface;
283 D3DLOCKED_RECT lockedRect;
285 RefPtr<IDirect3DTexture9> texture = InitTextures(aDeviceManager, aSize, aFormat,
286 surface, lockedRect);
287 if (!texture) {
288 return nullptr;
289 }
291 nsRefPtr<gfxImageSurface> imgSurface =
292 new gfxImageSurface(reinterpret_cast<unsigned char*>(lockedRect.pBits),
293 gfxIntSize(aSize.width, aSize.height),
294 lockedRect.Pitch,
295 gfxPlatform::GetPlatform()->OptimalFormatForContent(aSurface->GetContentType()));
297 nsRefPtr<gfxContext> context = new gfxContext(imgSurface);
298 context->SetSource(aSurface);
299 context->SetOperator(gfxContext::OPERATOR_SOURCE);
300 context->Paint();
302 FinishTextures(aDeviceManager, texture, surface);
304 return texture;
305 }
307 class D3D9TextureClientData : public TextureClientData
308 {
309 public:
310 D3D9TextureClientData(IDirect3DTexture9* aTexture)
311 : mTexture(aTexture)
312 {}
314 D3D9TextureClientData(gfxWindowsSurface* aWindowSurface)
315 : mWindowSurface(aWindowSurface)
316 {}
318 virtual void DeallocateSharedData(ISurfaceAllocator*) MOZ_OVERRIDE
319 {
320 mWindowSurface = nullptr;
321 mTexture = nullptr;
322 }
324 private:
325 RefPtr<IDirect3DTexture9> mTexture;
326 nsRefPtr<gfxWindowsSurface> mWindowSurface;
327 };
329 DataTextureSourceD3D9::DataTextureSourceD3D9(gfx::SurfaceFormat aFormat,
330 CompositorD3D9* aCompositor,
331 TextureFlags aFlags,
332 StereoMode aStereoMode)
333 : mFormat(aFormat)
334 , mCompositor(aCompositor)
335 , mCurrentTile(0)
336 , mFlags(aFlags)
337 , mIsTiled(false)
338 , mIterating(false)
339 {
340 mStereoMode = aStereoMode;
341 MOZ_COUNT_CTOR(DataTextureSourceD3D9);
342 }
344 DataTextureSourceD3D9::DataTextureSourceD3D9(gfx::SurfaceFormat aFormat,
345 gfx::IntSize aSize,
346 CompositorD3D9* aCompositor,
347 IDirect3DTexture9* aTexture,
348 TextureFlags aFlags)
349 : mFormat(aFormat)
350 , mCompositor(aCompositor)
351 , mCurrentTile(0)
352 , mFlags(aFlags)
353 , mIsTiled(false)
354 , mIterating(false)
355 {
356 mSize = aSize;
357 mTexture = aTexture;
358 mStereoMode = StereoMode::MONO;
359 MOZ_COUNT_CTOR(DataTextureSourceD3D9);
360 }
362 DataTextureSourceD3D9::~DataTextureSourceD3D9()
363 {
364 MOZ_COUNT_DTOR(DataTextureSourceD3D9);
365 }
367 IDirect3DTexture9*
368 DataTextureSourceD3D9::GetD3D9Texture()
369 {
370 return mIterating ? mTileTextures[mCurrentTile]
371 : mTexture;
372 }
374 bool
375 DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface,
376 nsIntRegion* aDestRegion,
377 gfx::IntPoint* aSrcOffset)
378 {
379 // Right now we only support full surface update. If aDestRegion is provided,
380 // It will be ignored. Incremental update with a source offset is only used
381 // on Mac so it is not clear that we ever will need to support it for D3D.
382 MOZ_ASSERT(!aSrcOffset);
384 if (!mCompositor || !mCompositor->device()) {
385 NS_WARNING("No D3D device to update the texture.");
386 return false;
387 }
388 mSize = aSurface->GetSize();
390 uint32_t bpp = 0;
392 _D3DFORMAT format = D3DFMT_A8R8G8B8;
393 mFormat = aSurface->GetFormat();
394 switch (mFormat) {
395 case SurfaceFormat::B8G8R8X8:
396 format = D3DFMT_X8R8G8B8;
397 bpp = 4;
398 break;
399 case SurfaceFormat::B8G8R8A8:
400 format = D3DFMT_A8R8G8B8;
401 bpp = 4;
402 break;
403 case SurfaceFormat::A8:
404 format = D3DFMT_A8;
405 bpp = 1;
406 break;
407 default:
408 NS_WARNING("Bad image format");
409 return false;
410 }
412 int32_t maxSize = mCompositor->GetMaxTextureSize();
413 DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
414 if ((mSize.width <= maxSize && mSize.height <= maxSize) ||
415 (mFlags & TEXTURE_DISALLOW_BIGIMAGE)) {
416 mTexture = DataToTexture(deviceManager,
417 aSurface->GetData(), aSurface->Stride(),
418 IntSize(mSize), format, bpp);
419 if (!mTexture) {
420 NS_WARNING("Could not upload texture");
421 Reset();
422 return false;
423 }
424 mIsTiled = false;
425 } else {
426 mIsTiled = true;
427 uint32_t tileCount = GetRequiredTilesD3D9(mSize.width, maxSize) *
428 GetRequiredTilesD3D9(mSize.height, maxSize);
429 mTileTextures.resize(tileCount);
430 mTexture = nullptr;
432 for (uint32_t i = 0; i < tileCount; i++) {
433 IntRect tileRect = GetTileRect(i);
434 unsigned char* data = aSurface->GetData() +
435 tileRect.y * aSurface->Stride() +
436 tileRect.x * bpp;
437 mTileTextures[i] = DataToTexture(deviceManager,
438 data,
439 aSurface->Stride(),
440 IntSize(tileRect.width, tileRect.height),
441 format,
442 bpp);
443 if (!mTileTextures[i]) {
444 NS_WARNING("Could not upload texture");
445 Reset();
446 return false;
447 }
448 }
449 }
451 return true;
452 }
454 bool
455 DataTextureSourceD3D9::Update(gfxWindowsSurface* aSurface)
456 {
457 MOZ_ASSERT(aSurface);
458 if (!mCompositor || !mCompositor->device()) {
459 NS_WARNING("No D3D device to update the texture.");
460 return false;
461 }
462 mSize = ToIntSize(aSurface->GetSize());
464 uint32_t bpp = 0;
466 _D3DFORMAT format = D3DFMT_A8R8G8B8;
467 mFormat = ImageFormatToSurfaceFormat(
468 gfxPlatform::GetPlatform()->OptimalFormatForContent(aSurface->GetContentType()));
469 switch (mFormat) {
470 case SurfaceFormat::B8G8R8X8:
471 format = D3DFMT_X8R8G8B8;
472 bpp = 4;
473 break;
474 case SurfaceFormat::B8G8R8A8:
475 format = D3DFMT_A8R8G8B8;
476 bpp = 4;
477 break;
478 case SurfaceFormat::A8:
479 format = D3DFMT_A8;
480 bpp = 1;
481 break;
482 default:
483 NS_WARNING("Bad image format");
484 return false;
485 }
487 int32_t maxSize = mCompositor->GetMaxTextureSize();
488 DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
489 if ((mSize.width <= maxSize && mSize.height <= maxSize) ||
490 (mFlags & TEXTURE_DISALLOW_BIGIMAGE)) {
491 mTexture = SurfaceToTexture(deviceManager, aSurface, mSize, format);
493 if (!mTexture) {
494 NS_WARNING("Could not upload texture");
495 Reset();
496 return false;
497 }
498 mIsTiled = false;
499 } else {
500 mIsTiled = true;
501 uint32_t tileCount = GetRequiredTilesD3D9(mSize.width, maxSize) *
502 GetRequiredTilesD3D9(mSize.height, maxSize);
503 mTileTextures.resize(tileCount);
504 mTexture = nullptr;
505 nsRefPtr<gfxImageSurface> imgSurface = aSurface->GetAsImageSurface();
507 for (uint32_t i = 0; i < tileCount; i++) {
508 IntRect tileRect = GetTileRect(i);
509 unsigned char* data = imgSurface->Data() +
510 tileRect.y * imgSurface->Stride() +
511 tileRect.x * bpp;
512 mTileTextures[i] = DataToTexture(deviceManager,
513 data,
514 imgSurface->Stride(),
515 IntSize(tileRect.width, tileRect.height),
516 format,
517 bpp);
518 if (!mTileTextures[i]) {
519 NS_WARNING("Could not upload texture");
520 Reset();
521 return false;
522 }
523 }
524 }
526 return true;
527 }
529 void
530 DataTextureSourceD3D9::SetCompositor(Compositor* aCompositor)
531 {
532 CompositorD3D9* d3dCompositor = static_cast<CompositorD3D9*>(aCompositor);
533 if (mCompositor && mCompositor != d3dCompositor) {
534 Reset();
535 }
536 mCompositor = d3dCompositor;
537 }
539 void
540 DataTextureSourceD3D9::Reset()
541 {
542 mSize.width = 0;
543 mSize.height = 0;
544 mIsTiled = false;
545 mTexture = nullptr;
546 mTileTextures.clear();
547 }
549 IntRect
550 DataTextureSourceD3D9::GetTileRect(uint32_t aTileIndex) const
551 {
552 uint32_t maxSize = mCompositor->GetMaxTextureSize();
553 uint32_t horizontalTiles = GetRequiredTilesD3D9(mSize.width, maxSize);
554 uint32_t verticalTiles = GetRequiredTilesD3D9(mSize.height, maxSize);
556 uint32_t verticalTile = aTileIndex / horizontalTiles;
557 uint32_t horizontalTile = aTileIndex % horizontalTiles;
559 return IntRect(horizontalTile * maxSize,
560 verticalTile * maxSize,
561 horizontalTile < (horizontalTiles - 1) ? maxSize : mSize.width % maxSize,
562 verticalTile < (verticalTiles - 1) ? maxSize : mSize.height % maxSize);
563 }
565 nsIntRect
566 DataTextureSourceD3D9::GetTileRect()
567 {
568 return ThebesIntRect(GetTileRect(mCurrentTile));
569 }
571 CairoTextureClientD3D9::CairoTextureClientD3D9(gfx::SurfaceFormat aFormat, TextureFlags aFlags)
572 : TextureClient(aFlags)
573 , mFormat(aFormat)
574 , mIsLocked(false)
575 , mNeedsClear(false)
576 , mLockRect(false)
577 {
578 MOZ_COUNT_CTOR(CairoTextureClientD3D9);
579 }
581 CairoTextureClientD3D9::~CairoTextureClientD3D9()
582 {
583 MOZ_COUNT_DTOR(CairoTextureClientD3D9);
584 }
586 bool
587 CairoTextureClientD3D9::Lock(OpenMode)
588 {
589 MOZ_ASSERT(!mIsLocked);
590 if (!IsValid() || !IsAllocated()) {
591 return false;
592 }
594 if (!gfxWindowsPlatform::GetPlatform()->GetD3D9Device()) {
595 // If the device has failed then we should not lock the surface,
596 // even if we could.
597 mD3D9Surface = nullptr;
598 return false;
599 }
601 if (!mD3D9Surface) {
602 HRESULT hr = mTexture->GetSurfaceLevel(0, getter_AddRefs(mD3D9Surface));
603 if (FAILED(hr)) {
604 NS_WARNING("Failed to get texture surface level.");
605 return false;
606 }
607 }
609 mIsLocked = true;
611 if (mNeedsClear) {
612 mDrawTarget = GetAsDrawTarget();
613 mDrawTarget->ClearRect(Rect(0, 0, GetSize().width, GetSize().height));
614 mNeedsClear = false;
615 }
617 return true;
618 }
620 void
621 CairoTextureClientD3D9::Unlock()
622 {
623 MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!");
624 if (mDrawTarget) {
625 mDrawTarget->Flush();
626 mDrawTarget = nullptr;
627 }
629 if (mLockRect) {
630 mD3D9Surface->UnlockRect();
631 mLockRect = false;
632 }
634 if (mSurface) {
635 mSurface = nullptr;
636 }
637 mIsLocked = false;
638 }
640 bool
641 CairoTextureClientD3D9::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
642 {
643 MOZ_ASSERT(IsValid());
644 if (!IsAllocated()) {
645 return false;
646 }
648 mTexture->AddRef(); // Release in TextureHostD3D9::TextureHostD3D9
649 aOutDescriptor = SurfaceDescriptorD3D9(reinterpret_cast<uintptr_t>(mTexture.get()));
650 return true;
651 }
653 TemporaryRef<gfx::DrawTarget>
654 CairoTextureClientD3D9::GetAsDrawTarget()
655 {
656 MOZ_ASSERT(mIsLocked && mD3D9Surface);
657 if (mDrawTarget) {
658 return mDrawTarget;
659 }
661 if (ContentForFormat(mFormat) == gfxContentType::COLOR) {
662 mSurface = new gfxWindowsSurface(mD3D9Surface);
663 if (!mSurface || mSurface->CairoStatus()) {
664 NS_WARNING("Could not create surface for d3d9 surface");
665 mSurface = nullptr;
666 return nullptr;
667 }
668 } else {
669 // gfxWindowsSurface don't support transparency so we can't use the d3d9
670 // windows surface optimization.
671 // Instead we have to use a gfxImageSurface and fallback for font drawing.
672 D3DLOCKED_RECT rect;
673 mD3D9Surface->LockRect(&rect, nullptr, 0);
674 mSurface = new gfxImageSurface((uint8_t*)rect.pBits, ThebesIntSize(mSize),
675 rect.Pitch, SurfaceFormatToImageFormat(mFormat));
676 mLockRect = true;
677 }
679 mDrawTarget =
680 gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mSurface, mSize);
682 return mDrawTarget;
683 }
685 bool
686 CairoTextureClientD3D9::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
687 {
688 MOZ_ASSERT(!IsAllocated());
689 mSize = aSize;
690 _D3DFORMAT format = SurfaceFormatToD3D9Format(mFormat);
692 DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
693 if (!deviceManager ||
694 !(mTexture = deviceManager->CreateTexture(mSize, format, D3DPOOL_SYSTEMMEM, nullptr))) {
695 NS_WARNING("Could not create d3d9 texture");
696 return false;
697 }
699 mNeedsClear = aFlags & ALLOC_CLEAR_BUFFER;
701 MOZ_ASSERT(mTexture);
702 return true;
703 }
705 TextureClientData*
706 CairoTextureClientD3D9::DropTextureData()
707 {
708 TextureClientData* data = new D3D9TextureClientData(mTexture);
709 mTexture = nullptr;
710 MarkInvalid();
711 return data;
712 }
714 DIBTextureClientD3D9::DIBTextureClientD3D9(gfx::SurfaceFormat aFormat, TextureFlags aFlags)
715 : TextureClient(aFlags)
716 , mFormat(aFormat)
717 , mIsLocked(false)
718 {
719 MOZ_COUNT_CTOR(DIBTextureClientD3D9);
720 }
722 DIBTextureClientD3D9::~DIBTextureClientD3D9()
723 {
724 MOZ_COUNT_DTOR(DIBTextureClientD3D9);
725 }
727 bool
728 DIBTextureClientD3D9::Lock(OpenMode)
729 {
730 MOZ_ASSERT(!mIsLocked);
731 if (!IsValid()) {
732 return false;
733 }
734 mIsLocked = true;
735 return true;
736 }
738 void
739 DIBTextureClientD3D9::Unlock()
740 {
741 MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!");
742 if (mDrawTarget) {
743 mDrawTarget->Flush();
744 mDrawTarget = nullptr;
745 }
747 mIsLocked = false;
748 }
750 bool
751 DIBTextureClientD3D9::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
752 {
753 MOZ_ASSERT(IsValid());
754 if (!IsAllocated()) {
755 return false;
756 }
757 MOZ_ASSERT(mSurface);
758 // The host will release this ref when it receives the surface descriptor.
759 // We AddRef in case we die before the host receives the pointer.
760 aOutDescriptor = SurfaceDescriptorDIB(reinterpret_cast<uintptr_t>(mSurface.get()));
761 mSurface->AddRef();
762 return true;
763 }
765 TemporaryRef<gfx::DrawTarget>
766 DIBTextureClientD3D9::GetAsDrawTarget()
767 {
768 MOZ_ASSERT(mIsLocked && IsAllocated());
770 if (!mDrawTarget) {
771 mDrawTarget =
772 gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mSurface, mSize);
773 }
775 return mDrawTarget;
776 }
778 bool
779 DIBTextureClientD3D9::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
780 {
781 MOZ_ASSERT(!IsAllocated());
782 mSize = aSize;
784 mSurface = new gfxWindowsSurface(gfxIntSize(aSize.width, aSize.height),
785 SurfaceFormatToImageFormat(mFormat));
786 if (!mSurface || mSurface->CairoStatus())
787 {
788 NS_WARNING("Could not create surface");
789 mSurface = nullptr;
790 return false;
791 }
793 return true;
794 }
796 TextureClientData*
797 DIBTextureClientD3D9::DropTextureData()
798 {
799 TextureClientData* data = new D3D9TextureClientData(mSurface);
800 mSurface = nullptr;
801 MarkInvalid();
802 return data;
803 }
805 SharedTextureClientD3D9::SharedTextureClientD3D9(gfx::SurfaceFormat aFormat, TextureFlags aFlags)
806 : TextureClient(aFlags)
807 , mFormat(aFormat)
808 , mHandle(0)
809 , mIsLocked(false)
810 {
811 MOZ_COUNT_CTOR(SharedTextureClientD3D9);
812 }
814 SharedTextureClientD3D9::~SharedTextureClientD3D9()
815 {
816 MOZ_COUNT_DTOR(SharedTextureClientD3D9);
817 }
819 TextureClientData*
820 SharedTextureClientD3D9::DropTextureData()
821 {
822 TextureClientData* data = new D3D9TextureClientData(mTexture);
823 mTexture = nullptr;
824 MarkInvalid();
825 return data;
826 }
828 bool
829 SharedTextureClientD3D9::Lock(OpenMode)
830 {
831 MOZ_ASSERT(!mIsLocked);
832 if (!IsValid()) {
833 return false;
834 }
835 mIsLocked = true;
836 return true;
837 }
839 void
840 SharedTextureClientD3D9::Unlock()
841 {
842 MOZ_ASSERT(mIsLocked, "Unlock called while the texture is not locked!");
843 }
845 bool
846 SharedTextureClientD3D9::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
847 {
848 MOZ_ASSERT(IsValid());
849 if (!IsAllocated()) {
850 return false;
851 }
853 aOutDescriptor = SurfaceDescriptorD3D10((WindowsHandle)(mHandle), mFormat, GetSize());
854 return true;
855 }
857 TextureHostD3D9::TextureHostD3D9(TextureFlags aFlags,
858 const SurfaceDescriptorD3D9& aDescriptor)
859 : TextureHost(aFlags)
860 , mFormat(SurfaceFormat::UNKNOWN)
861 , mIsLocked(false)
862 {
863 mTexture = reinterpret_cast<IDirect3DTexture9*>(aDescriptor.texture());
864 mTexture->Release(); // see AddRef in CairoTextureClientD3D9::ToSurfaceDescriptor
865 MOZ_ASSERT(mTexture);
866 D3DSURFACE_DESC desc;
867 HRESULT hr = mTexture->GetLevelDesc(0, &desc);
868 if (!FAILED(hr)) {
869 mFormat = D3D9FormatToSurfaceFormat(desc.Format);
870 mSize.width = desc.Width;
871 mSize.height = desc.Height;
872 }
873 }
875 bool
876 DataTextureSourceD3D9::UpdateFromTexture(IDirect3DTexture9* aTexture,
877 const nsIntRegion* aRegion)
878 {
879 MOZ_ASSERT(aTexture);
881 D3DSURFACE_DESC desc;
882 HRESULT hr = aTexture->GetLevelDesc(0, &desc);
883 if (FAILED(hr)) {
884 return false;
885 } else {
886 // If we changed the compositor, the size might have been reset to zero
887 // Otherwise the texture size must not change.
888 MOZ_ASSERT(mFormat == D3D9FormatToSurfaceFormat(desc.Format));
889 MOZ_ASSERT(!mSize.width || mSize.width == desc.Width);
890 MOZ_ASSERT(!mSize.height || mSize.height == desc.Height);
891 mSize = IntSize(desc.Width, desc.Height);
892 }
894 DeviceManagerD3D9* dm = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
895 if (!mTexture) {
896 mTexture = dm->CreateTexture(mSize, SurfaceFormatToD3D9Format(mFormat),
897 D3DPOOL_DEFAULT, this);
898 if (!mTexture) {
899 NS_WARNING("Failed to create a texture");
900 return false;
901 }
902 }
904 RefPtr<IDirect3DSurface9> srcSurface;
905 RefPtr<IDirect3DSurface9> dstSurface;
907 hr = aTexture->GetSurfaceLevel(0, byRef(srcSurface));
908 if (FAILED(hr)) {
909 return false;
910 }
911 hr = mTexture->GetSurfaceLevel(0, byRef(dstSurface));
912 if (FAILED(hr)) {
913 return false;
914 }
916 if (aRegion) {
917 nsIntRegionRectIterator iter(*aRegion);
918 const nsIntRect *iterRect;
919 while ((iterRect = iter.Next())) {
920 RECT rect;
921 rect.left = iterRect->x;
922 rect.top = iterRect->y;
923 rect.right = iterRect->XMost();
924 rect.bottom = iterRect->YMost();
926 POINT point;
927 point.x = iterRect->x;
928 point.y = iterRect->y;
929 hr = dm->device()->UpdateSurface(srcSurface, &rect, dstSurface, &point);
930 if (FAILED(hr)) {
931 NS_WARNING("Failed Update the surface");
932 return false;
933 }
934 }
935 } else {
936 hr = dm->device()->UpdateSurface(srcSurface, nullptr, dstSurface, nullptr);
937 if (FAILED(hr)) {
938 NS_WARNING("Failed Update the surface");
939 return false;
940 }
941 }
942 mIsTiled = false;
943 return true;
944 }
946 void
947 TextureHostD3D9::Updated(const nsIntRegion* aRegion)
948 {
949 if (!mTexture) {
950 return;
951 }
953 if (!mTextureSource) {
954 mTextureSource = new DataTextureSourceD3D9(mFormat, mSize, mCompositor,
955 nullptr, mFlags);
956 }
958 mTextureSource->UpdateFromTexture(mTexture, aRegion);
959 }
961 IDirect3DDevice9*
962 TextureHostD3D9::GetDevice()
963 {
964 return mCompositor ? mCompositor->device() : nullptr;
965 }
967 void
968 TextureHostD3D9::SetCompositor(Compositor* aCompositor)
969 {
970 mCompositor = static_cast<CompositorD3D9*>(aCompositor);
971 if (mTextureSource) {
972 mTextureSource->SetCompositor(aCompositor);
973 }
974 }
976 NewTextureSource*
977 TextureHostD3D9::GetTextureSources()
978 {
979 MOZ_ASSERT(mIsLocked);
980 return mTextureSource;
981 }
983 bool
984 TextureHostD3D9::Lock()
985 {
986 MOZ_ASSERT(!mIsLocked);
987 mIsLocked = true;
988 return true;
989 }
991 void
992 TextureHostD3D9::Unlock()
993 {
994 MOZ_ASSERT(mIsLocked);
995 mIsLocked = false;
996 }
998 void
999 TextureHostD3D9::DeallocateDeviceData()
1000 {
1001 mTextureSource = nullptr;
1002 }
1004 DIBTextureHostD3D9::DIBTextureHostD3D9(TextureFlags aFlags,
1005 const SurfaceDescriptorDIB& aDescriptor)
1006 : TextureHost(aFlags)
1007 , mIsLocked(false)
1008 {
1009 // We added an extra ref for transport, so we shouldn't AddRef now.
1010 mSurface =
1011 dont_AddRef(reinterpret_cast<gfxWindowsSurface*>(aDescriptor.surface()));
1012 MOZ_ASSERT(mSurface);
1014 mSize = ToIntSize(mSurface->GetSize());
1015 mFormat = ImageFormatToSurfaceFormat(
1016 gfxPlatform::GetPlatform()->OptimalFormatForContent(mSurface->GetContentType()));
1017 }
1019 NewTextureSource*
1020 DIBTextureHostD3D9::GetTextureSources()
1021 {
1022 if (!mTextureSource) {
1023 Updated();
1024 }
1026 return mTextureSource;
1027 }
1029 void
1030 DIBTextureHostD3D9::Updated(const nsIntRegion*)
1031 {
1032 if (!mTextureSource) {
1033 mTextureSource = new DataTextureSourceD3D9(mFormat, mCompositor, mFlags);
1034 }
1036 if (!mTextureSource->Update(mSurface)) {
1037 mTextureSource = nullptr;
1038 }
1039 }
1041 bool
1042 DIBTextureHostD3D9::Lock()
1043 {
1044 MOZ_ASSERT(!mIsLocked);
1045 mIsLocked = true;
1046 return true;
1047 }
1049 void
1050 DIBTextureHostD3D9::Unlock()
1051 {
1052 MOZ_ASSERT(mIsLocked);
1053 mIsLocked = false;
1054 }
1056 void
1057 DIBTextureHostD3D9::SetCompositor(Compositor* aCompositor)
1058 {
1059 mCompositor = static_cast<CompositorD3D9*>(aCompositor);
1060 }
1062 void
1063 DIBTextureHostD3D9::DeallocateDeviceData()
1064 {
1065 mTextureSource = nullptr;
1066 }
1068 DXGITextureHostD3D9::DXGITextureHostD3D9(TextureFlags aFlags,
1069 const SurfaceDescriptorD3D10& aDescriptor)
1070 : TextureHost(aFlags)
1071 , mHandle(aDescriptor.handle())
1072 , mFormat(aDescriptor.format())
1073 , mSize(aDescriptor.size())
1074 , mIsLocked(false)
1075 {
1076 MOZ_ASSERT(mHandle);
1077 }
1079 NewTextureSource*
1080 DXGITextureHostD3D9::GetTextureSources()
1081 {
1082 return mTextureSource;
1083 }
1085 bool
1086 DXGITextureHostD3D9::Lock()
1087 {
1088 DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
1089 if (!deviceManager) {
1090 NS_WARNING("trying to lock a TextureHost without a D3D device");
1091 return false;
1092 }
1094 if (!mTextureSource) {
1095 nsRefPtr<IDirect3DTexture9> tex;
1096 HRESULT hr = deviceManager->device()->CreateTexture(mSize.width,
1097 mSize.height,
1098 1,
1099 D3DUSAGE_RENDERTARGET,
1100 SurfaceFormatToD3D9Format(mFormat),
1101 D3DPOOL_DEFAULT,
1102 getter_AddRefs(tex),
1103 (HANDLE*)&mHandle);
1104 if (FAILED(hr)) {
1105 NS_WARNING("Failed to open shared texture");
1106 return false;
1107 }
1109 mTextureSource = new DataTextureSourceD3D9(mFormat, mSize, mCompositor, tex);
1110 }
1112 MOZ_ASSERT(!mIsLocked);
1113 mIsLocked = true;
1114 return true;
1115 }
1117 void
1118 DXGITextureHostD3D9::Unlock()
1119 {
1120 MOZ_ASSERT(mIsLocked);
1121 mIsLocked = false;
1122 }
1124 void
1125 DXGITextureHostD3D9::SetCompositor(Compositor* aCompositor)
1126 {
1127 mCompositor = static_cast<CompositorD3D9*>(aCompositor);
1128 }
1130 void
1131 DXGITextureHostD3D9::DeallocateDeviceData()
1132 {
1133 mTextureSource = nullptr;
1134 }
1136 }
1137 }