Advertisement
Guest User

Untitled

a guest
Jan 13th, 2019
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 27.35 KB | None | 0 0
  1. diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h
  2. --- a/gfx/2d/2D.h
  3. +++ b/gfx/2d/2D.h
  4. @@ -55,16 +55,17 @@ typedef FT_LibraryRec_ *FT_Library;
  5.  struct FT_FaceRec_;
  6.  typedef FT_FaceRec_ *FT_Face;
  7.  
  8.  typedef int FT_Error;
  9.  
  10.  struct ID3D11Texture2D;
  11.  struct ID3D11Device;
  12.  struct ID2D1Device;
  13. +struct ID2D1DeviceContext;
  14.  struct IDWriteFactory;
  15.  struct IDWriteRenderingParams;
  16.  struct IDWriteFontFace;
  17.  struct IDWriteFontCollection;
  18.  
  19.  class GrContext;
  20.  class SkCanvas;
  21.  struct gfxFontStyle;
  22. @@ -1788,16 +1789,17 @@ class GFX2D_API Factory {
  23.    static RefPtr<ID3D11Device> GetDirect3D11Device();
  24.    static RefPtr<ID2D1Device> GetD2D1Device(uint32_t *aOutSeqNo = nullptr);
  25.    static bool HasD2D1Device();
  26.    static RefPtr<IDWriteFactory> GetDWriteFactory();
  27.    static RefPtr<IDWriteFactory> EnsureDWriteFactory();
  28.    static bool SupportsD2D1();
  29.    static RefPtr<IDWriteFontCollection> GetDWriteSystemFonts(
  30.        bool aUpdate = false);
  31. +  static RefPtr<ID2D1DeviceContext> GetD2DDeviceContext();
  32.  
  33.    static uint64_t GetD2DVRAMUsageDrawTarget();
  34.    static uint64_t GetD2DVRAMUsageSourceSurface();
  35.    static void D2DCleanup();
  36.  
  37.    static already_AddRefed<ScaledFont> CreateScaledFontForDWriteFont(
  38.        IDWriteFontFace *aFontFace, const gfxFontStyle *aStyle,
  39.        const RefPtr<UnscaledFont> &aUnscaledFont, Float aSize,
  40. @@ -1807,17 +1809,18 @@ class GFX2D_API Factory {
  41.    static void SetSystemTextQuality(uint8_t aQuality);
  42.  
  43.   private:
  44.    static StaticRefPtr<ID2D1Device> mD2D1Device;
  45.    static StaticRefPtr<ID3D11Device> mD3D11Device;
  46.    static StaticRefPtr<IDWriteFactory> mDWriteFactory;
  47.    static bool mDWriteFactoryInitialized;
  48.    static StaticRefPtr<IDWriteFontCollection> mDWriteSystemFonts;
  49. -
  50. +  static StaticRefPtr<ID2D1DeviceContext> mMTDC;
  51. +  static StaticRefPtr<ID2D1DeviceContext> mOMTDC;
  52.   protected:
  53.    // This guards access to the singleton devices above, as well as the
  54.    // singleton devices in DrawTargetD2D1.
  55.    static StaticMutex mDeviceLock;
  56.    // This synchronizes access between different D2D drawtargets and their
  57.    // implied dependency graph.
  58.    static StaticMutex mDTDependencyLock;
  59.  
  60. diff --git a/gfx/2d/DrawTargetD2D1.cpp b/gfx/2d/DrawTargetD2D1.cpp
  61. --- a/gfx/2d/DrawTargetD2D1.cpp
  62. +++ b/gfx/2d/DrawTargetD2D1.cpp
  63. @@ -38,17 +38,18 @@ StaticRefPtr<ID2D1Factory1> DrawTargetD2
  64.  RefPtr<ID2D1Factory1> D2DFactory() { return DrawTargetD2D1::factory(); }
  65.  
  66.  DrawTargetD2D1::DrawTargetD2D1()
  67.      : mPushedLayers(1),
  68.        mSnapshotLock(make_shared<Mutex>("DrawTargetD2D1::mSnapshotLock")),
  69.        mUsedCommandListsSincePurge(0),
  70.        mTransformedGlyphsSinceLastPurge(0),
  71.        mComplexBlendsWithListInList(0),
  72. -      mDeviceSeq(0) {}
  73. +      mDeviceSeq(0),
  74. +      mIsInitialized(false) {}
  75.  
  76.  DrawTargetD2D1::~DrawTargetD2D1() {
  77.    PopAllClips();
  78.  
  79.    if (mSnapshot) {
  80.      MutexAutoLock lock(*mSnapshotLock);
  81.      // We may hold the only reference. MarkIndependent will clear mSnapshot;
  82.      // keep the snapshot object alive so it doesn't get destroyed while
  83. @@ -81,16 +82,20 @@ DrawTargetD2D1::~DrawTargetD2D1() {
  84.      for (TargetSet::iterator iter = mDependingOnTargets.begin();
  85.           iter != mDependingOnTargets.end(); iter++) {
  86.        (*iter)->mDependentTargets.erase(this);
  87.      }
  88.    }
  89.  }
  90.  
  91.  already_AddRefed<SourceSurface> DrawTargetD2D1::Snapshot() {
  92. +  if (!EnsureInitialized()) {
  93. +    return nullptr;
  94. +  }
  95. +
  96.    MutexAutoLock lock(*mSnapshotLock);
  97.    if (mSnapshot) {
  98.      RefPtr<SourceSurface> snapshot(mSnapshot);
  99.      return snapshot.forget();
  100.    }
  101.    PopAllClips();
  102.  
  103.    Flush();
  104. @@ -120,16 +125,19 @@ bool DrawTargetD2D1::EnsureLuminanceEffe
  105.    mLuminanceEffect->SetValue(D2D1_COLORMATRIX_PROP_COLOR_MATRIX, matrix);
  106.    mLuminanceEffect->SetValue(D2D1_COLORMATRIX_PROP_ALPHA_MODE,
  107.                               D2D1_COLORMATRIX_ALPHA_MODE_STRAIGHT);
  108.    return true;
  109.  }
  110.  
  111.  already_AddRefed<SourceSurface> DrawTargetD2D1::IntoLuminanceSource(
  112.      LuminanceType aLuminanceType, float aOpacity) {
  113. +  if (!EnsureInitialized()) {
  114. +    return nullptr;
  115. +  }
  116.    if ((aLuminanceType != LuminanceType::LUMINANCE) ||
  117.        // See bug 1372577, some race condition where we get invalid
  118.        // results with D2D in the parent process. Fallback in that case.
  119.        XRE_IsParentProcess()) {
  120.      return DrawTarget::IntoLuminanceSource(aLuminanceType, aOpacity);
  121.    }
  122.  
  123.    // Create the luminance effect
  124. @@ -263,16 +271,19 @@ void DrawTargetD2D1::DrawFilter(FilterNo
  125.    FinalizeDrawing(aOptions.mCompositionOp, ColorPattern(Color()));
  126.  }
  127.  
  128.  void DrawTargetD2D1::DrawSurfaceWithShadow(SourceSurface *aSurface,
  129.                                             const Point &aDest,
  130.                                             const Color &aColor,
  131.                                             const Point &aOffset, Float aSigma,
  132.                                             CompositionOp aOperator) {
  133. +  if (!EnsureInitialized()) {
  134. +    return;
  135. +  }
  136.    MarkChanged();
  137.    mDC->SetTransform(D2D1::IdentityMatrix());
  138.    mTransformDirty = true;
  139.  
  140.    Matrix mat;
  141.    RefPtr<ID2D1Image> image =
  142.        GetImageForSurface(aSurface, mat, ExtendMode::CLAMP, nullptr, false);
  143.  
  144. @@ -315,16 +326,19 @@ void DrawTargetD2D1::DrawSurfaceWithShad
  145.    if (aSurface->GetFormat() != SurfaceFormat::A8) {
  146.      D2D1_POINT_2F imgPoint = D2DPoint(aDest);
  147.      mDC->DrawImage(image, &imgPoint, nullptr, D2D1_INTERPOLATION_MODE_LINEAR,
  148.                     D2DCompositionMode(aOperator));
  149.    }
  150.  }
  151.  
  152.  void DrawTargetD2D1::ClearRect(const Rect &aRect) {
  153. +  if (!EnsureInitialized()) {
  154. +    return;
  155. +  }
  156.    MarkChanged();
  157.  
  158.    PopAllClips();
  159.  
  160.    PushClipRect(aRect);
  161.  
  162.    if (mTransformDirty || !mTransform.IsIdentity()) {
  163.      mDC->SetTransform(D2D1::IdentityMatrix());
  164. @@ -371,16 +385,19 @@ void DrawTargetD2D1::ClearRect(const Rec
  165.  
  166.    PopClip();
  167.  
  168.    return;
  169.  }
  170.  
  171.  void DrawTargetD2D1::MaskSurface(const Pattern &aSource, SourceSurface *aMask,
  172.                                   Point aOffset, const DrawOptions &aOptions) {
  173. +  if (!EnsureInitialized()) {
  174. +    return;
  175. +  }
  176.    MarkChanged();
  177.  
  178.    RefPtr<ID2D1Bitmap> bitmap;
  179.  
  180.    Matrix mat = Matrix::Translation(aOffset);
  181.    RefPtr<ID2D1Image> image =
  182.        GetImageForSurface(aMask, mat, ExtendMode::CLAMP, nullptr);
  183.  
  184. @@ -447,16 +464,19 @@ void DrawTargetD2D1::MaskSurface(const P
  185.    mDC->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
  186.  
  187.    FinalizeDrawing(aOptions.mCompositionOp, aSource);
  188.  }
  189.  
  190.  void DrawTargetD2D1::CopySurface(SourceSurface *aSurface,
  191.                                   const IntRect &aSourceRect,
  192.                                   const IntPoint &aDestination) {
  193. +  if (!EnsureInitialized()) {
  194. +    return;
  195. +  }
  196.    MarkChanged();
  197.  
  198.    PopAllClips();
  199.  
  200.    mDC->SetTransform(D2D1::IdentityMatrix());
  201.    mTransformDirty = true;
  202.  
  203.    Matrix mat = Matrix::Translation(aDestination.x - aSourceRect.X(),
  204. @@ -783,23 +803,29 @@ void DrawTargetD2D1::PushClipGeometry(ID
  205.    }
  206.  }
  207.  
  208.  void DrawTargetD2D1::PushClip(const Path *aPath) {
  209.    if (aPath->GetBackendType() != BackendType::DIRECT2D1_1) {
  210.      gfxDebug() << *this << ": Ignoring clipping call for incompatible path.";
  211.      return;
  212.    }
  213. +  if (!EnsureInitialized()) {
  214. +    return;
  215. +  }
  216.  
  217.    RefPtr<PathD2D> pathD2D = static_cast<PathD2D *>(const_cast<Path *>(aPath));
  218.  
  219.    PushClipGeometry(pathD2D->GetGeometry(), D2DMatrix(mTransform));
  220.  }
  221.  
  222.  void DrawTargetD2D1::PushClipRect(const Rect &aRect) {
  223. +  if (!EnsureInitialized()) {
  224. +    return;
  225. +  }
  226.    if (!mTransform.IsRectilinear()) {
  227.      // Whoops, this isn't a rectangle in device space, Direct2D will not deal
  228.      // with this transform the way we want it to.
  229.      // See remarks:
  230.      // http://msdn.microsoft.com/en-us/library/dd316860%28VS.85%29.aspx
  231.      RefPtr<ID2D1Geometry> geom = ConvertRectToGeometry(D2DRect(aRect));
  232.      return PushClipGeometry(geom, D2DMatrix(mTransform));
  233.    }
  234. @@ -823,16 +849,19 @@ void DrawTargetD2D1::PushClipRect(const
  235.      mDC->PushAxisAlignedClip(
  236.          clip.mBounds, clip.mIsPixelAligned ? D2D1_ANTIALIAS_MODE_ALIASED
  237.                                             : D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
  238.    }
  239.  }
  240.  
  241.  void DrawTargetD2D1::PushDeviceSpaceClipRects(const IntRect *aRects,
  242.                                                uint32_t aCount) {
  243. +  if (!EnsureInitialized()) {
  244. +    return;
  245. +  }
  246.    // Build a path for the union of the rects.
  247.    RefPtr<ID2D1PathGeometry> path;
  248.    factory()->CreatePathGeometry(getter_AddRefs(path));
  249.    RefPtr<ID2D1GeometrySink> sink;
  250.    path->Open(getter_AddRefs(sink));
  251.    sink->SetFillMode(D2D1_FILL_MODE_WINDING);
  252.    for (uint32_t i = 0; i < aCount; i++) {
  253.      const IntRect &rect = aRects[i];
  254. @@ -846,16 +875,19 @@ void DrawTargetD2D1::PushDeviceSpaceClip
  255.    sink->Close();
  256.  
  257.    // The path is in device-space, so there is no transform needed,
  258.    // and all rects are pixel aligned.
  259.    PushClipGeometry(path, D2D1::IdentityMatrix(), true);
  260.  }
  261.  
  262.  void DrawTargetD2D1::PopClip() {
  263. +  if (!EnsureInitialized()) {
  264. +    return;
  265. +  }
  266.    mCurrentClippedGeometry = nullptr;
  267.    if (CurrentLayer().mPushedClips.empty()) {
  268.      gfxDevCrash(LogReason::UnbalancedClipStack)
  269.          << "DrawTargetD2D1::PopClip: No clip to pop.";
  270.      return;
  271.    }
  272.  
  273.    if (CurrentLayer().mClipsArePushed) {
  274. @@ -867,16 +899,19 @@ void DrawTargetD2D1::PopClip() {
  275.    }
  276.    CurrentLayer().mPushedClips.pop_back();
  277.  }
  278.  
  279.  void DrawTargetD2D1::PushLayer(bool aOpaque, Float aOpacity,
  280.                                 SourceSurface *aMask,
  281.                                 const Matrix &aMaskTransform,
  282.                                 const IntRect &aBounds, bool aCopyBackground) {
  283. +  if (!EnsureInitialized()) {
  284. +    return;
  285. +  }
  286.    D2D1_LAYER_OPTIONS1 options = D2D1_LAYER_OPTIONS1_NONE;
  287.  
  288.    if (aOpaque) {
  289.      options |= D2D1_LAYER_OPTIONS1_IGNORE_ALPHA;
  290.    }
  291.    if (aCopyBackground) {
  292.      options |= D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND;
  293.    }
  294. @@ -935,17 +970,19 @@ void DrawTargetD2D1::PushLayer(bool aOpa
  295.  
  296.    mDC->SetTarget(CurrentTarget());
  297.  
  298.    mUsedCommandListsSincePurge++;
  299.  }
  300.  
  301.  void DrawTargetD2D1::PopLayer() {
  302.    MOZ_ASSERT(CurrentLayer().mPushedClips.size() == 0);
  303. -
  304. +  if (!EnsureInitialized()) {
  305. +    return;
  306. +  }
  307.    RefPtr<ID2D1CommandList> list = CurrentLayer().mCurrentList;
  308.    mPermitSubpixelAA = CurrentLayer().mOldPermitSubpixelAA;
  309.  
  310.    mPushedLayers.pop_back();
  311.    mDC->SetTarget(CurrentTarget());
  312.  
  313.    list->Close();
  314.    mDC->SetTransform(D2D1::IdentityMatrix());
  315. @@ -960,47 +997,48 @@ void DrawTargetD2D1::PopLayer() {
  316.  }
  317.  
  318.  already_AddRefed<SourceSurface> DrawTargetD2D1::CreateSourceSurfaceFromData(
  319.      unsigned char *aData, const IntSize &aSize, int32_t aStride,
  320.      SurfaceFormat aFormat) const {
  321.    RefPtr<ID2D1Bitmap1> bitmap;
  322.  
  323.    HRESULT hr =
  324. -      mDC->CreateBitmap(D2DIntSize(aSize), aData, aStride,
  325. +      Factory::GetD2DDeviceContext()->CreateBitmap(D2DIntSize(aSize), aData, aStride,
  326.                          D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_NONE,
  327.                                                  D2DPixelFormat(aFormat)),
  328.                          getter_AddRefs(bitmap));
  329.  
  330.    if (FAILED(hr) || !bitmap) {
  331.      gfxCriticalError(
  332.          CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize)))
  333.          << "[D2D1.1] 1CreateBitmap failure " << aSize << " Code: " << hexa(hr)
  334.          << " format " << (int)aFormat;
  335.      return nullptr;
  336.    }
  337.  
  338. -  return MakeAndAddRef<SourceSurfaceD2D1>(bitmap.get(), mDC, aFormat, aSize);
  339. +  return MakeAndAddRef<SourceSurfaceD2D1>(bitmap.get(), Factory::GetD2DDeviceContext().get(), aFormat, aSize);
  340.  }
  341.  
  342.  already_AddRefed<DrawTarget> DrawTargetD2D1::CreateSimilarDrawTarget(
  343.      const IntSize &aSize, SurfaceFormat aFormat) const {
  344.    RefPtr<DrawTargetD2D1> dt = new DrawTargetD2D1();
  345.  
  346.    if (!dt->Init(aSize, aFormat)) {
  347.      return nullptr;
  348.    }
  349.  
  350.    return dt.forget();
  351.  }
  352.  
  353.  bool DrawTargetD2D1::CanCreateSimilarDrawTarget(const IntSize &aSize,
  354.                                                  SurfaceFormat aFormat) const {
  355. -  return (mDC->GetMaximumBitmapSize() >= UINT32(aSize.width) &&
  356. -          mDC->GetMaximumBitmapSize() >= UINT32(aSize.height));
  357. +  RefPtr<ID2D1DeviceContext> dc = Factory::GetD2DDeviceContext();
  358. +  return (dc->GetMaximumBitmapSize() >= UINT32(aSize.width) &&
  359. +          dc->GetMaximumBitmapSize() >= UINT32(aSize.height));
  360.  }
  361.  
  362.  already_AddRefed<PathBuilder> DrawTargetD2D1::CreatePathBuilder(
  363.      FillRule aFillRule) const {
  364.    RefPtr<ID2D1PathGeometry> path;
  365.    HRESULT hr = factory()->CreatePathGeometry(getter_AddRefs(path));
  366.  
  367.    if (FAILED(hr)) {
  368. @@ -1037,17 +1075,17 @@ already_AddRefed<GradientStops> DrawTarg
  369.  
  370.    for (uint32_t i = 0; i < aNumStops; i++) {
  371.      stops[i].position = rawStops[i].offset;
  372.      stops[i].color = D2DColor(rawStops[i].color);
  373.    }
  374.  
  375.    RefPtr<ID2D1GradientStopCollection1> stopCollection;
  376.  
  377. -  HRESULT hr = mDC->CreateGradientStopCollection(
  378. +  HRESULT hr = Factory::GetD2DDeviceContext()->CreateGradientStopCollection(
  379.        stops, aNumStops, D2D1_COLOR_SPACE_SRGB, D2D1_COLOR_SPACE_SRGB,
  380.        D2D1_BUFFER_PRECISION_8BPC_UNORM, D2DExtend(aExtendMode, Axis::BOTH),
  381.        D2D1_COLOR_INTERPOLATION_MODE_PREMULTIPLIED,
  382.        getter_AddRefs(stopCollection));
  383.    delete[] stops;
  384.  
  385.    if (FAILED(hr)) {
  386.      gfxWarning() << *this << ": Failed to create GradientStopCollection. Code: "
  387. @@ -1077,145 +1115,49 @@ void DrawTargetD2D1::GetGlyphRasterizati
  388.      if (aGlyphMetrics[i].mWidth > 0 && aGlyphMetrics[i].mHeight > 0) {
  389.        aGlyphMetrics[i].mWidth += 2.0f;
  390.        aGlyphMetrics[i].mXBearing -= 1.0f;
  391.      }
  392.    }
  393.  }
  394.  
  395.  bool DrawTargetD2D1::Init(ID3D11Texture2D *aTexture, SurfaceFormat aFormat) {
  396. -  HRESULT hr;
  397. -
  398.    RefPtr<ID2D1Device> device = Factory::GetD2D1Device(&mDeviceSeq);
  399.    if (!device) {
  400.      gfxCriticalNote << "[D2D1.1] Failed to obtain a device for "
  401.                         "DrawTargetD2D1::Init(ID3D11Texture2D*, SurfaceFormat).";
  402.      return false;
  403.    }
  404.  
  405. -  hr = device->CreateDeviceContext(
  406. -      D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS,
  407. -      getter_AddRefs(mDC));
  408. -
  409. -  if (FAILED(hr)) {
  410. -    gfxCriticalError() << "[D2D1.1] 1Failed to create a DeviceContext, code: "
  411. -                       << hexa(hr) << " format " << (int)aFormat;
  412. -    return false;
  413. -  }
  414. -
  415. -  RefPtr<IDXGISurface> dxgiSurface;
  416.    aTexture->QueryInterface(
  417.        __uuidof(IDXGISurface),
  418. -      (void **)((IDXGISurface **)getter_AddRefs(dxgiSurface)));
  419. -  if (!dxgiSurface) {
  420. +      (void **)((IDXGISurface **)getter_AddRefs(mSurface)));
  421. +  if (!mSurface) {
  422.      gfxCriticalError() << "[D2D1.1] Failed to obtain a DXGI surface.";
  423.      return false;
  424.    }
  425.  
  426. -  D2D1_BITMAP_PROPERTIES1 props;
  427. -  props.dpiX = 96;
  428. -  props.dpiY = 96;
  429. -  props.pixelFormat = D2DPixelFormat(aFormat);
  430. -  props.colorContext = nullptr;
  431. -  props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
  432. -  hr = mDC->CreateBitmapFromDxgiSurface(
  433. -      dxgiSurface, props, (ID2D1Bitmap1 **)getter_AddRefs(mBitmap));
  434. +  mFormat = aFormat;
  435.  
  436. -  if (FAILED(hr)) {
  437. -    gfxCriticalError() << "[D2D1.1] CreateBitmapFromDxgiSurface failure Code: "
  438. -                       << hexa(hr) << " format " << (int)aFormat;
  439. -    return false;
  440. -  }
  441. -
  442. -  mFormat = aFormat;
  443.    D3D11_TEXTURE2D_DESC desc;
  444.    aTexture->GetDesc(&desc);
  445.    mSize.width = desc.Width;
  446.    mSize.height = desc.Height;
  447.  
  448. -  // This single solid color brush system is not very 'threadsafe', however,
  449. -  // issueing multiple drawing commands simultaneously to a single drawtarget
  450. -  // from multiple threads is unexpected since there's no way to guarantee
  451. -  // ordering in that situation anyway.
  452. -  hr = mDC->CreateSolidColorBrush(D2D1::ColorF(0, 0),
  453. -                                  getter_AddRefs(mSolidColorBrush));
  454. -
  455. -  if (FAILED(hr)) {
  456. -    gfxCriticalError() << "[D2D1.1] Failure creating solid color brush (I1).";
  457. -    return false;
  458. -  }
  459. -
  460. -  mDC->SetTarget(CurrentTarget());
  461. -
  462. -  mDC->BeginDraw();
  463. -
  464. -  CurrentLayer().mIsOpaque = aFormat == SurfaceFormat::B8G8R8X8;
  465. -
  466.    return true;
  467.  }
  468.  
  469.  bool DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat) {
  470. -  HRESULT hr;
  471. -
  472.    RefPtr<ID2D1Device> device = Factory::GetD2D1Device(&mDeviceSeq);
  473.    if (!device) {
  474.      gfxCriticalNote << "[D2D1.1] Failed to obtain a device for "
  475.                         "DrawTargetD2D1::Init(IntSize, SurfaceFormat).";
  476.      return false;
  477.    }
  478.  
  479. -  hr = device->CreateDeviceContext(
  480. -      D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS,
  481. -      getter_AddRefs(mDC));
  482. -
  483. -  if (FAILED(hr)) {
  484. -    gfxCriticalError() << "[D2D1.1] 2Failed to create a DeviceContext, code: "
  485. -                       << hexa(hr) << " format " << (int)aFormat;
  486. -    return false;
  487. -  }
  488. -
  489. -  if (mDC->GetMaximumBitmapSize() < UINT32(aSize.width) ||
  490. -      mDC->GetMaximumBitmapSize() < UINT32(aSize.height)) {
  491. -    // This is 'ok', so don't assert
  492. -    gfxCriticalNote << "[D2D1.1] Attempt to use unsupported surface size "
  493. -                    << aSize;
  494. -    return false;
  495. -  }
  496. -
  497. -  D2D1_BITMAP_PROPERTIES1 props;
  498. -  props.dpiX = 96;
  499. -  props.dpiY = 96;
  500. -  props.pixelFormat = D2DPixelFormat(aFormat);
  501. -  props.colorContext = nullptr;
  502. -  props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
  503. -  hr = mDC->CreateBitmap(D2DIntSize(aSize), nullptr, 0, props,
  504. -                         (ID2D1Bitmap1 **)getter_AddRefs(mBitmap));
  505. -
  506. -  if (FAILED(hr)) {
  507. -    gfxCriticalError() << "[D2D1.1] 3CreateBitmap failure " << aSize
  508. -                       << " Code: " << hexa(hr) << " format " << (int)aFormat;
  509. -    return false;
  510. -  }
  511. -
  512. -  mDC->SetTarget(CurrentTarget());
  513. -
  514. -  hr = mDC->CreateSolidColorBrush(D2D1::ColorF(0, 0),
  515. -                                  getter_AddRefs(mSolidColorBrush));
  516. -
  517. -  if (FAILED(hr)) {
  518. -    gfxCriticalError() << "[D2D1.1] Failure creating solid color brush (I2).";
  519. -    return false;
  520. -  }
  521. -
  522. -  mDC->BeginDraw();
  523. -
  524. -  CurrentLayer().mIsOpaque = aFormat == SurfaceFormat::B8G8R8X8;
  525. -
  526. -  mDC->Clear();
  527. -
  528.    mFormat = aFormat;
  529.    mSize = aSize;
  530.  
  531.    return true;
  532.  }
  533.  
  534.  /**
  535.   * Private helpers.
  536. @@ -1317,16 +1259,104 @@ void DrawTargetD2D1::FlushInternal(bool
  537.    // We no longer depend on any target.
  538.    for (TargetSet::iterator iter = mDependingOnTargets.begin();
  539.         iter != mDependingOnTargets.end(); iter++) {
  540.      (*iter)->mDependentTargets.erase(this);
  541.    }
  542.    mDependingOnTargets.clear();
  543.  }
  544.  
  545. +bool DrawTargetD2D1::EnsureInitialized() {
  546. +  if (mIsInitialized) {
  547. +    return true;
  548. +  }
  549. +
  550. +  HRESULT hr;
  551. +
  552. +  RefPtr<ID2D1Device> device = Factory::GetD2D1Device(&mDeviceSeq);
  553. +  if (!device) {
  554. +    gfxCriticalNote << "[D2D1.1] Failed to obtain a device for "
  555. +                       "DrawTargetD2D1::EnsureInitialized().";
  556. +    return false;
  557. +  }
  558. +
  559. +  hr = device->CreateDeviceContext(
  560. +      D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS,
  561. +      getter_AddRefs(mDC));
  562. +
  563. +  if (FAILED(hr)) {
  564. +    gfxCriticalError() << "[D2D1.1] 2Failed to create a DeviceContext, code: "
  565. +                       << hexa(hr) << " format " << (int)mFormat;
  566. +    return false;
  567. +  }
  568. +
  569. +  if (!mSurface) {
  570. +    if (mDC->GetMaximumBitmapSize() < UINT32(mSize.width) ||
  571. +        mDC->GetMaximumBitmapSize() < UINT32(mSize.height)) {
  572. +      // This is 'ok', so don't assert
  573. +      gfxCriticalNote << "[D2D1.1] Attempt to use unsupported surface size "
  574. +                      << mSize;
  575. +      return false;
  576. +    }
  577. +
  578. +    D2D1_BITMAP_PROPERTIES1 props;
  579. +    props.dpiX = 96;
  580. +    props.dpiY = 96;
  581. +    props.pixelFormat = D2DPixelFormat(mFormat);
  582. +    props.colorContext = nullptr;
  583. +    props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
  584. +    hr = mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props,
  585. +                           (ID2D1Bitmap1 **)getter_AddRefs(mBitmap));
  586. +
  587. +    if (FAILED(hr)) {
  588. +      gfxCriticalError() << "[D2D1.1] 3CreateBitmap failure " << mSize
  589. +                         << " Code: " << hexa(hr) << " format " << (int)mFormat;
  590. +      return false;
  591. +    }
  592. +  } else {
  593. +    D2D1_BITMAP_PROPERTIES1 props;
  594. +    props.dpiX = 96;
  595. +    props.dpiY = 96;
  596. +    props.pixelFormat = D2DPixelFormat(mFormat);
  597. +    props.colorContext = nullptr;
  598. +    props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
  599. +    hr = mDC->CreateBitmapFromDxgiSurface(
  600. +        mSurface, props, (ID2D1Bitmap1 **)getter_AddRefs(mBitmap));
  601. +
  602. +    if (FAILED(hr)) {
  603. +      gfxCriticalError()
  604. +          << "[D2D1.1] CreateBitmapFromDxgiSurface failure Code: " << hexa(hr)
  605. +          << " format " << (int)mFormat;
  606. +      return false;
  607. +    }
  608. +  }
  609. +
  610. +  mDC->SetTarget(CurrentTarget());
  611. +
  612. +  hr = mDC->CreateSolidColorBrush(D2D1::ColorF(0, 0),
  613. +                                  getter_AddRefs(mSolidColorBrush));
  614. +
  615. +  if (FAILED(hr)) {
  616. +    gfxCriticalError() << "[D2D1.1] Failure creating solid color brush (I2).";
  617. +    return false;
  618. +  }
  619. +
  620. +  mDC->BeginDraw();
  621. +
  622. +  CurrentLayer().mIsOpaque = mFormat == SurfaceFormat::B8G8R8X8;
  623. +
  624. +  if (!mSurface) {
  625. +    mDC->Clear();
  626. +  }
  627. +
  628. +  mIsInitialized = true;
  629. +
  630. +  return true;
  631. +}
  632. +
  633.  void DrawTargetD2D1::MarkChanged() {
  634.    if (mSnapshot) {
  635.      MutexAutoLock lock(*mSnapshotLock);
  636.      if (mSnapshot->hasOneRef()) {
  637.        // Just destroy it, since no-one else knows about it.
  638.        mSnapshot = nullptr;
  639.      } else {
  640.        mSnapshot->DrawTargetWillChange();
  641. @@ -1356,16 +1386,19 @@ bool DrawTargetD2D1::ShouldClipTemporary
  642.    bool patternSupported = IsPatternSupportedByD2D(aPattern);
  643.    return patternSupported && !CurrentLayer().mIsOpaque &&
  644.           D2DSupportsCompositeMode(aOp) && IsOperatorBoundByMask(aOp) &&
  645.           aClipIsComplex;
  646.  }
  647.  
  648.  void DrawTargetD2D1::PrepareForDrawing(CompositionOp aOp,
  649.                                         const Pattern &aPattern) {
  650. +  if (!EnsureInitialized()) {
  651. +    return;
  652. +  }
  653.    MarkChanged();
  654.  
  655.    bool patternSupported = IsPatternSupportedByD2D(aPattern);
  656.  
  657.    if (D2DSupportsPrimitiveBlendMode(aOp) && patternSupported) {
  658.      // It's important to do this before FlushTransformToDC! As this will cause
  659.      // the transform to become dirty.
  660.      PushAllClips();
  661. @@ -2075,17 +2108,17 @@ already_AddRefed<SourceSurface> DrawTarg
  662.  
  663.    RefPtr<ID2D1Bitmap1> bitmap;
  664.    {
  665.      DataSourceSurface::ScopedMap map(data, DataSourceSurface::READ);
  666.      if (MOZ2D_WARN_IF(!map.IsMapped())) {
  667.        return nullptr;
  668.      }
  669.  
  670. -    HRESULT hr = mDC->CreateBitmap(
  671. +    HRESULT hr = Factory::GetD2DDeviceContext()->CreateBitmap(
  672.          D2DIntSize(data->GetSize()), map.GetData(), map.GetStride(),
  673.          D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_NONE,
  674.                                  D2DPixelFormat(data->GetFormat())),
  675.          getter_AddRefs(bitmap));
  676.  
  677.      if (FAILED(hr)) {
  678.        gfxCriticalError(CriticalLog::DefaultOptions(
  679.            Factory::ReasonableSurfaceSize(data->GetSize())))
  680. @@ -2093,17 +2126,17 @@ already_AddRefed<SourceSurface> DrawTarg
  681.            << " Code: " << hexa(hr) << " format " << (int)data->GetFormat();
  682.      }
  683.    }
  684.  
  685.    if (!bitmap) {
  686.      return data.forget();
  687.    }
  688.  
  689. -  return MakeAndAddRef<SourceSurfaceD2D1>(bitmap.get(), mDC, data->GetFormat(),
  690. +  return MakeAndAddRef<SourceSurfaceD2D1>(bitmap.get(), Factory::GetD2DDeviceContext().get(), data->GetFormat(),
  691.                                            data->GetSize());
  692.  }
  693.  
  694.  void DrawTargetD2D1::PushD2DLayer(ID2D1DeviceContext *aDC,
  695.                                    ID2D1Geometry *aGeometry,
  696.                                    const D2D1_MATRIX_3X2_F &aTransform,
  697.                                    bool aPixelAligned, bool aForceIgnoreAlpha,
  698.                                    const D2D1_RECT_F &aMaxRect) {
  699. diff --git a/gfx/2d/DrawTargetD2D1.h b/gfx/2d/DrawTargetD2D1.h
  700. --- a/gfx/2d/DrawTargetD2D1.h
  701. +++ b/gfx/2d/DrawTargetD2D1.h
  702. @@ -169,16 +169,17 @@ class DrawTargetD2D1 : public DrawTarget
  703.  
  704.    static uint64_t mVRAMUsageDT;
  705.    static uint64_t mVRAMUsageSS;
  706.  
  707.   private:
  708.    friend class SourceSurfaceD2D1;
  709.  
  710.    void FlushInternal(bool aHasDependencyMutex = false);
  711. +  bool EnsureInitialized();
  712.  
  713.    typedef std::unordered_set<DrawTargetD2D1 *> TargetSet;
  714.  
  715.    // This function will mark the surface as changing, and make sure any
  716.    // copy-on-write snapshots are notified.
  717.    void MarkChanged();
  718.    bool ShouldClipTemporarySurfaceDrawing(CompositionOp aOp,
  719.                                           const Pattern &aPattern,
  720. @@ -306,14 +307,17 @@ class DrawTargetD2D1 : public DrawTarget
  721.    static StaticRefPtr<ID2D1Factory1> mFactory;
  722.    // This value is uesed to verify if the DrawTarget is created by a stale
  723.    // device.
  724.    uint32_t mDeviceSeq;
  725.  
  726.    // List of effects we use
  727.    bool EnsureLuminanceEffect();
  728.    RefPtr<ID2D1Effect> mLuminanceEffect;
  729. +
  730. +  bool mIsInitialized;
  731. +  RefPtr<IDXGISurface> mSurface;
  732.  };
  733.  
  734.  }  // namespace gfx
  735.  }  // namespace mozilla
  736.  
  737.  #endif /* MOZILLA_GFX_DRAWTARGETD2D_H_ */
  738. diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp
  739. --- a/gfx/2d/Factory.cpp
  740. +++ b/gfx/2d/Factory.cpp
  741. @@ -198,16 +198,18 @@ StaticMutex Factory::mFTLock;
  742.  #endif
  743.  
  744.  #ifdef WIN32
  745.  // Note: mDeviceLock must be held when mutating these values.
  746.  static uint32_t mDeviceSeq = 0;
  747.  StaticRefPtr<ID3D11Device> Factory::mD3D11Device;
  748.  StaticRefPtr<ID2D1Device> Factory::mD2D1Device;
  749.  StaticRefPtr<IDWriteFactory> Factory::mDWriteFactory;
  750. +StaticRefPtr<ID2D1DeviceContext> Factory::mMTDC;
  751. +StaticRefPtr<ID2D1DeviceContext> Factory::mOMTDC;
  752.  bool Factory::mDWriteFactoryInitialized = false;
  753.  StaticRefPtr<IDWriteFontCollection> Factory::mDWriteSystemFonts;
  754.  StaticMutex Factory::mDeviceLock;
  755.  StaticMutex Factory::mDTDependencyLock;
  756.  #endif
  757.  
  758.  DrawEventRecorder* Factory::mRecorder;
  759.  
  760. @@ -848,16 +850,38 @@ RefPtr<IDWriteFontCollection> Factory::G
  761.      gfxWarning() << "Failed to create DWrite system font collection";
  762.      return nullptr;
  763.    }
  764.    mDWriteSystemFonts = systemFonts;
  765.  
  766.    return mDWriteSystemFonts;
  767.  }
  768.  
  769. +RefPtr<ID2D1DeviceContext> Factory::GetD2DDeviceContext() {
  770. +  StaticRefPtr<ID2D1DeviceContext>* ptr;
  771. +
  772. +  if (NS_IsMainThread()) {
  773. +    ptr = &mMTDC;
  774. +  } else {
  775. +    ptr = &mOMTDC;
  776. +  }
  777. +
  778. +  if (*ptr) {
  779. +    return *ptr;
  780. +  }
  781. +
  782. +  RefPtr<ID2D1DeviceContext> dc;
  783. +  HRESULT hr = mD2D1Device->CreateDeviceContext(
  784. +      D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS,
  785. +      getter_AddRefs(dc));
  786. +  *ptr = dc;
  787. +
  788. +  return *ptr;
  789. +}
  790. +
  791.  bool Factory::SupportsD2D1() { return !!D2DFactory(); }
  792.  
  793.  BYTE sSystemTextQuality = CLEARTYPE_QUALITY;
  794.  void Factory::SetSystemTextQuality(uint8_t aQuality) {
  795.    sSystemTextQuality = aQuality;
  796.  }
  797.  
  798.  uint64_t Factory::GetD2DVRAMUsageDrawTarget() {
  799. diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp
  800. --- a/gfx/layers/d3d11/TextureD3D11.cpp
  801. +++ b/gfx/layers/d3d11/TextureD3D11.cpp
  802. @@ -334,22 +334,22 @@ bool DXGITextureData::PrepareDrawTargetI
  803.        return false;
  804.      }
  805.    }
  806.  
  807.    // Reset transform
  808.    mDrawTarget->SetTransform(Matrix());
  809.  
  810.    if (mNeedsClear) {
  811. -    mDrawTarget->ClearRect(Rect(0, 0, mSize.width, mSize.height));
  812. +    //mDrawTarget->ClearRect(Rect(0, 0, mSize.width, mSize.height));
  813.      mNeedsClear = false;
  814.    }
  815.    if (mNeedsClearWhite) {
  816. -    mDrawTarget->FillRect(Rect(0, 0, mSize.width, mSize.height),
  817. -                          ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
  818. +    //mDrawTarget->FillRect(Rect(0, 0, mSize.width, mSize.height),
  819. +    //                      ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
  820.      mNeedsClearWhite = false;
  821.    }
  822.  
  823.    return true;
  824.  }
  825.  
  826.  void D3D11TextureData::Unlock() { UnlockD3DTexture(mTexture.get()); }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement