gfx/layers/d3d9/TextureD3D9.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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()
  1001   mTextureSource = nullptr;
  1004 DIBTextureHostD3D9::DIBTextureHostD3D9(TextureFlags aFlags,
  1005                                        const SurfaceDescriptorDIB& aDescriptor)
  1006   : TextureHost(aFlags)
  1007   , mIsLocked(false)
  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()));
  1019 NewTextureSource*
  1020 DIBTextureHostD3D9::GetTextureSources()
  1022   if (!mTextureSource) {
  1023     Updated();
  1026   return mTextureSource;
  1029 void
  1030 DIBTextureHostD3D9::Updated(const nsIntRegion*)
  1032   if (!mTextureSource) {
  1033     mTextureSource = new DataTextureSourceD3D9(mFormat, mCompositor, mFlags);
  1036   if (!mTextureSource->Update(mSurface)) {
  1037     mTextureSource = nullptr;
  1041 bool
  1042 DIBTextureHostD3D9::Lock()
  1044   MOZ_ASSERT(!mIsLocked);
  1045   mIsLocked = true;
  1046   return true;
  1049 void
  1050 DIBTextureHostD3D9::Unlock()
  1052   MOZ_ASSERT(mIsLocked);
  1053   mIsLocked = false;
  1056 void
  1057 DIBTextureHostD3D9::SetCompositor(Compositor* aCompositor)
  1059   mCompositor = static_cast<CompositorD3D9*>(aCompositor);
  1062 void
  1063 DIBTextureHostD3D9::DeallocateDeviceData()
  1065   mTextureSource = nullptr;
  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)
  1076   MOZ_ASSERT(mHandle);
  1079 NewTextureSource*
  1080 DXGITextureHostD3D9::GetTextureSources()
  1082   return mTextureSource;
  1085 bool
  1086 DXGITextureHostD3D9::Lock()
  1088   DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
  1089   if (!deviceManager) {
  1090     NS_WARNING("trying to lock a TextureHost without a D3D device");
  1091     return false;
  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;
  1109     mTextureSource = new DataTextureSourceD3D9(mFormat, mSize, mCompositor, tex);
  1112   MOZ_ASSERT(!mIsLocked);
  1113   mIsLocked = true;
  1114   return true;
  1117 void
  1118 DXGITextureHostD3D9::Unlock()
  1120   MOZ_ASSERT(mIsLocked);
  1121   mIsLocked = false;
  1124 void
  1125 DXGITextureHostD3D9::SetCompositor(Compositor* aCompositor)
  1127   mCompositor = static_cast<CompositorD3D9*>(aCompositor);
  1130 void
  1131 DXGITextureHostD3D9::DeallocateDeviceData()
  1133   mTextureSource = nullptr;

mercurial