gfx/layers/d3d11/TextureD3D11.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 "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 }

mercurial