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

mercurial