Bug 784382 - Part 2: Use new ID2D1DeviceContext interface in Azure. r=jrmuizel
authorBas Schouten <bschouten@mozilla.com>
Sun, 07 Oct 2012 01:43:16 +0200
changeset 109537 13ec2ee2b44798882ad2e58a0d349b699266688f
parent 109536 d3afcd4f3cc0f29bdf87e57417a3a85c8c801b51
child 109538 ecd4c43042193c599d446d712ac265319b70dc33
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjrmuizel
bugs784382
milestone18.0a1
Bug 784382 - Part 2: Use new ID2D1DeviceContext interface in Azure. r=jrmuizel
gfx/2d/DrawTargetD2D.cpp
gfx/2d/DrawTargetD2D.h
gfx/2d/HelpersD2D.h
gfx/2d/PathD2D.h
gfx/2d/moz-d2d1-1.h
--- a/gfx/2d/DrawTargetD2D.cpp
+++ b/gfx/2d/DrawTargetD2D.cpp
@@ -988,26 +988,17 @@ DrawTargetD2D::PushClip(const Path *aPat
   mPushedClips.push_back(clip);
 
   // The transform of clips is relative to the world matrix, since we use the total
   // transform for the clips, make the world matrix identity.
   mRT->SetTransform(D2D1::IdentityMatrix());
   mTransformDirty = true;
 
   if (mClipsArePushed) {
-    D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
-
-    if (mFormat == FORMAT_B8G8R8X8) {
-      options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
-    }
-
-    mRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), pathD2D->mGeometry,
-                                         D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
-                                         clip.mTransform, 1.0f, nullptr,
-                                         options), clip.mLayer);
+    PushD2DLayer(pathD2D->mGeometry, clip.mLayer, clip.mTransform);
   }
 }
 
 void
 DrawTargetD2D::PushClipRect(const Rect &aRect)
 {
   mCurrentClipMaskTexture = nullptr;
   mCurrentClippedGeometry = nullptr;
@@ -1821,26 +1812,17 @@ DrawTargetD2D::PopAllClips()
 }
 
 void
 DrawTargetD2D::PushClipsToRT(ID2D1RenderTarget *aRT)
 {
   for (std::vector<PushedClip>::iterator iter = mPushedClips.begin();
         iter != mPushedClips.end(); iter++) {
     if (iter->mLayer) {
-      D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
-
-      if (mFormat == FORMAT_B8G8R8X8) {
-        options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
-      }
-
-      aRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), iter->mPath->mGeometry,
-                                            D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
-                                            iter->mTransform, 1.0f, nullptr,
-                                            options), iter->mLayer);
+      PushD2DLayer(iter->mPath->mGeometry, iter->mLayer, iter->mTransform);
     } else {
       aRT->PushAxisAlignedClip(iter->mBounds, iter->mIsPixelAligned ? D2D1_ANTIALIAS_MODE_ALIASED : D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
     }
   }
 }
 
 void
 DrawTargetD2D::PopClipsFromRT(ID2D1RenderTarget *aRT)
@@ -2713,10 +2695,37 @@ DrawTargetD2D::SetScissorToRect(IntRect 
   } else {
     rect.left = rect.top = INT32_MIN;
     rect.right = rect.bottom = INT32_MAX;
   }
 
   mDevice->RSSetScissorRects(1, &rect);
 }
 
+void
+DrawTargetD2D::PushD2DLayer(ID2D1Geometry *aGeometry, ID2D1Layer *aLayer, const D2D1_MATRIX_3X2_F &aTransform)
+{
+  D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
+  D2D1_LAYER_OPTIONS1 options1 =  D2D1_LAYER_OPTIONS1_NONE;
+
+  if (mFormat == FORMAT_B8G8R8X8) {
+    options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
+    options1 = D2D1_LAYER_OPTIONS1_IGNORE_ALPHA | D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND;
+  }
+
+	RefPtr<ID2D1DeviceContext> dc;
+	HRESULT hr = mRT->QueryInterface(IID_ID2D1DeviceContext, (void**)((ID2D1DeviceContext**)byRef(dc)));
+
+	if (FAILED(hr)) {
+	    mRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), aGeometry,
+				                                   D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, aTransform,
+				                                   1.0, nullptr, options),
+				             aLayer);
+	} else {
+	    dc->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(), aGeometry,
+				                                   D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, aTransform,
+				                                   1.0, nullptr, options1),
+				            aLayer);
+	}
+}
+
 }
 }
--- a/gfx/2d/DrawTargetD2D.h
+++ b/gfx/2d/DrawTargetD2D.h
@@ -206,16 +206,18 @@ private:
 
   void SetupEffectForRadialGradient(const RadialGradientPattern *aPattern);
   void SetupStateForRendering();
 
   // Set the scissor rect to a certain IntRects, resets the scissor rect to
   // surface bounds when NULL is specified.
   void SetScissorToRect(IntRect *aRect);
 
+  void PushD2DLayer(ID2D1Geometry *aGeometry, ID2D1Layer *aLayer, const D2D1_MATRIX_3X2_F &aTransform);
+
   static const uint32_t test = 4;
 
   IntSize mSize;
 
   RefPtr<ID3D10Device1> mDevice;
   RefPtr<ID3D10Texture2D> mTexture;
   RefPtr<ID3D10Texture2D> mCurrentClipMaskTexture;
   RefPtr<ID2D1Geometry> mCurrentClippedGeometry;
--- a/gfx/2d/HelpersD2D.h
+++ b/gfx/2d/HelpersD2D.h
@@ -1,17 +1,18 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_HELPERSD2D_H_
 #define MOZILLA_GFX_HELPERSD2D_H_
 
-#include <d2d1.h>
+#include "moz-d2d1-1.h"
+
 #include <dwrite.h>
 #include "2D.h"
 
 #include "ScaledFontDWrite.h"
 
 namespace mozilla {
 namespace gfx {
 
--- a/gfx/2d/PathD2D.h
+++ b/gfx/2d/PathD2D.h
@@ -2,17 +2,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_PATHD2D_H_
 #define MOZILLA_GFX_PATHD2D_H_
 
 #include "2D.h"
-#include <d2d1.h>
+#include "moz-d2d1-1.h"
 
 namespace mozilla {
 namespace gfx {
 
 class PathD2D;
 
 class PathBuilderD2D : public PathBuilder
 {
new file mode 100644
--- /dev/null
+++ b/gfx/2d/moz-d2d1-1.h
@@ -0,0 +1,367 @@
+//---------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation.  All rights reserved.
+//
+// This file is automatically generated.  Please do not edit it directly.
+//
+// File name: D2D1_1.h
+//---------------------------------------------------------------------------
+#pragma once
+
+#ifndef _D2D1_1_H_
+#ifndef _D2D1_H_
+#include <d2d1.h>
+#endif // #ifndef _D2D1_H_
+
+//+-----------------------------------------------------------------------------
+//
+//  Flag:
+//      D2D1_LAYER_OPTIONS1
+//
+//  Synopsis:
+//      Specifies how the layer contents should be prepared.
+//
+//------------------------------------------------------------------------------
+typedef enum D2D1_LAYER_OPTIONS1
+{
+        D2D1_LAYER_OPTIONS1_NONE = 0,
+        D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND = 1,
+        D2D1_LAYER_OPTIONS1_IGNORE_ALPHA = 2,
+        D2D1_LAYER_OPTIONS1_FORCE_DWORD = 0xffffffff
+
+} D2D1_LAYER_OPTIONS1;
+
+//+-----------------------------------------------------------------------------
+//
+//  Struct:
+//      D2D1_LAYER_PARAMETERS1
+//
+//  Synopsis:
+//      All parameters related to pushing a layer.
+//
+//------------------------------------------------------------------------------
+typedef struct D2D1_LAYER_PARAMETERS1
+{
+    D2D1_RECT_F contentBounds;
+    ID2D1Geometry *geometricMask;
+    D2D1_ANTIALIAS_MODE maskAntialiasMode;
+    D2D1_MATRIX_3X2_F maskTransform;
+    FLOAT opacity;
+    ID2D1Brush *opacityBrush;
+    D2D1_LAYER_OPTIONS1 layerOptions;
+
+} D2D1_LAYER_PARAMETERS1;
+
+DEFINE_ENUM_FLAG_OPERATORS(D2D1_LAYER_OPTIONS1);
+
+#ifndef DX_DECLARE_INTERFACE
+#define DX_DECLARE_INTERFACE(x) DECLSPEC_UUID(x) DECLSPEC_NOVTABLE
+#endif
+
+namespace D2D1
+{
+    D2D1FORCEINLINE
+    D2D1_LAYER_PARAMETERS1
+    LayerParameters1(
+        CONST D2D1_RECT_F &contentBounds = D2D1::InfiniteRect(),
+        ID2D1Geometry *geometricMask = NULL,
+        D2D1_ANTIALIAS_MODE maskAntialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
+        D2D1_MATRIX_3X2_F maskTransform = D2D1::IdentityMatrix(),
+        FLOAT opacity = 1.0,
+        ID2D1Brush *opacityBrush = NULL,
+        D2D1_LAYER_OPTIONS1 layerOptions = D2D1_LAYER_OPTIONS1_NONE
+        )
+    {
+        D2D1_LAYER_PARAMETERS1 layerParameters = { 0 };
+
+        layerParameters.contentBounds = contentBounds;
+        layerParameters.geometricMask = geometricMask;
+        layerParameters.maskAntialiasMode = maskAntialiasMode;
+        layerParameters.maskTransform = maskTransform;
+        layerParameters.opacity = opacity;
+        layerParameters.opacityBrush = opacityBrush;
+        layerParameters.layerOptions = layerOptions;
+
+        return layerParameters;
+    }
+}
+
+DEFINE_GUID(IID_ID2D1DeviceContext, 0xe8f7fe7a, 0x191c, 0x466d, 0xad, 0x95, 0x97, 0x56, 0x78, 0xbd, 0xa9, 0x98);
+
+//+-----------------------------------------------------------------------------
+//
+//  Interface:
+//      ID2D1DeviceContext
+//
+//  Synopsis:
+//      The device context represents a set of state and a command buffer that is used
+//      to render to a target bitmap.
+//
+//------------------------------------------------------------------------------
+interface DX_DECLARE_INTERFACE("e8f7fe7a-191c-466d-ad95-975678bda998") ID2D1DeviceContext  : public ID2D1RenderTarget
+{
+    
+    
+    //
+    // Creates a bitmap with extended bitmap properties, potentially from a block of
+    // memory.
+    //
+    STDMETHOD(CreateBitmap)() PURE;
+    
+    //
+    // Create a D2D bitmap by copying a WIC bitmap.
+    //
+    STDMETHOD(CreateBitmapFromWicBitmap)() PURE;    
+    
+    //
+    // Creates a color context from a color space.  If the space is Custom, the context
+    // is initialized from the profile/profileSize arguments.  Otherwise the context is
+    // initialized with the profile bytes associated with the space and
+    // profile/profileSize are ignored.
+    //
+    STDMETHOD(CreateColorContext)() PURE;
+    
+    STDMETHOD(CreateColorContextFromFilename)() PURE;
+    
+    STDMETHOD(CreateColorContextFromWicColorContext)() PURE;
+    
+    
+    //
+    // Creates a bitmap from a DXGI surface with a set of extended properties.
+    //
+    STDMETHOD(CreateBitmapFromDxgiSurface)() PURE;
+    
+    
+    //
+    // Create a new effect, the effect must either be built in or previously registered
+    // through ID2D1Factory1::RegisterEffectFromStream or
+    // ID2D1Factory1::RegisterEffectFromString.
+    //
+    STDMETHOD(CreateEffect)() PURE;
+    
+    
+    //
+    // A gradient stop collection represents a set of stops in an ideal unit length.
+    // This is the source resource for a linear gradient and radial gradient brush.
+    //
+    STDMETHOD(CreateGradientStopCollection)() PURE;
+    
+    //
+    // Creates an image brush, the input image can be any type of image, including a
+    // bitmap, effect and a command list.
+    //
+    STDMETHOD(CreateImageBrush)() PURE;
+    
+    STDMETHOD(CreateBitmapBrush)() PURE;
+
+    //
+    // Creates a new command list.
+    //
+    STDMETHOD(CreateCommandList)() PURE;
+    
+    
+    //
+    // Indicates whether the format is supported by D2D.
+    //
+    STDMETHOD_(BOOL, IsDxgiFormatSupported)() CONST PURE;
+    
+    
+    //
+    // Indicates whether the buffer precision is supported by D2D.
+    //
+    STDMETHOD_(BOOL, IsBufferPrecisionSupported)() CONST PURE;
+    
+    
+    //
+    // This retrieves the local-space bounds in DIPs of the current image using the
+    // device context DPI.
+    //
+    STDMETHOD(GetImageLocalBounds)() CONST PURE;
+    
+    
+    //
+    // This retrieves the world-space bounds in DIPs of the current image using the
+    // device context DPI.
+    //
+    STDMETHOD(GetImageWorldBounds)() CONST PURE;
+    
+    
+    //
+    // Retrieves the world-space bounds in DIPs of the glyph run using the device
+    // context DPI.
+    //
+    STDMETHOD(GetGlyphRunWorldBounds)() CONST PURE;
+    
+    
+    //
+    // Retrieves the device associated with this device context.
+    //
+    STDMETHOD_(void, GetDevice)() CONST PURE;
+    
+    
+    //
+    // Sets the target for this device context to point to the given image. The image
+    // can be a command list or a bitmap created with the D2D1_BITMAP_OPTIONS_TARGET
+    // flag.
+    //
+    STDMETHOD_(void, SetTarget)() PURE;
+    
+    
+    //
+    // Gets the target that this device context is currently pointing to.
+    //
+    STDMETHOD_(void, GetTarget)() CONST PURE;
+    
+    
+    //
+    // Sets tuning parameters for internal rendering inside the device context.
+    //
+    STDMETHOD_(void, SetRenderingControls)() PURE;
+    
+    
+    //
+    // This retrieves the rendering controls currently selected into the device
+    // context.
+    //
+    STDMETHOD_(void, GetRenderingControls)() CONST PURE;
+    
+    
+    //
+    // Changes the primitive blending mode for all of the rendering operations.
+    //
+    STDMETHOD_(void, SetPrimitiveBlend)() PURE;
+    
+    
+    //
+    // Returns the primitive blend currently selected into the device context.
+    //
+    STDMETHOD_(void, GetPrimitiveBlend)(
+        ) CONST PURE;
+    
+    
+    //
+    // Changes the units used for all of the rendering operations.
+    //
+    STDMETHOD_(void, SetUnitMode)() PURE;
+    
+    
+    //
+    // Returns the unit mode currently set on the device context.
+    //
+    STDMETHOD_(void, GetUnitMode)(
+        ) CONST PURE;
+    
+    
+    //
+    // Draws the glyph run with an extended description to describe the glyphs.
+    //
+    STDMETHOD_(void, DrawGlyphRun)() PURE;
+    
+    //
+    // Draw an image to the device context. The image represents either a concrete
+    // bitmap or the output of an effect graph.
+    //
+    STDMETHOD_(void, DrawImage)() PURE;
+    
+    
+    //
+    // Draw a metafile to the device context.
+    //
+    STDMETHOD_(void, DrawGdiMetafile)() PURE;
+    
+    STDMETHOD_(void, DrawBitmap)() PURE;
+    
+    
+    //
+    // Push a layer on the device context.
+    //
+    STDMETHOD_(void, PushLayer)(
+        _In_ CONST D2D1_LAYER_PARAMETERS1 *layerParameters,
+        _In_opt_ ID2D1Layer *layer 
+        ) PURE;
+    
+    using ID2D1RenderTarget::PushLayer;
+    
+    
+    //
+    // This indicates that a portion of an effect's input is invalid. This method can
+    // be called many times.
+    //
+    STDMETHOD(InvalidateEffectInputRectangle)() PURE;
+    
+    
+    //
+    // Gets the number of invalid ouptut rectangles that have accumulated at the
+    // effect.
+    //
+    STDMETHOD(GetEffectInvalidRectangleCount)() PURE;
+    
+    
+    //
+    // Gets the invalid rectangles that are at the output of the effect.
+    //
+    STDMETHOD(GetEffectInvalidRectangles)() PURE;
+    
+    
+    //
+    // Gets the maximum region of each specified input which would be used during a
+    // subsequent rendering operation
+    //
+    STDMETHOD(GetEffectRequiredInputRectangles)() PURE;
+    
+    
+    //
+    // Fill using the alpha channel of the supplied opacity mask bitmap. The brush
+    // opacity will be modulated by the mask. The render target antialiasing mode must
+    // be set to aliased.
+    //
+    STDMETHOD_(void, FillOpacityMask)() PURE;
+    
+ 
+    HRESULT CreateBitmap1() { return S_OK; }
+    HRESULT CreateBitmap2() { return S_OK; }
+    HRESULT CreateBitmap3() { return S_OK; }
+    HRESULT CreateBitmap4() { return S_OK; }
+    
+    HRESULT CreateImageBrush1() { return S_OK; }
+    HRESULT CreateImageBrush2() { return S_OK; }
+    
+    HRESULT CreateBitmapBrush1() { return S_OK; }
+    HRESULT CreateBitmapBrush2() { return S_OK; }
+    HRESULT CreateBitmapBrush3() { return S_OK; }
+
+    //
+    // Draws the output of the effect as an image.
+    //
+    void DrawImage1() {}
+    void DrawImage2() {}
+    void DrawImage3() {}
+    void DrawImage4() {}
+    void DrawImage5() {}
+    void DrawImage6() {}
+    void DrawImage7() {}
+    
+    void
+    PushLayer(
+        CONST D2D1_LAYER_PARAMETERS1 &layerParameters,
+        _In_opt_ ID2D1Layer *layer 
+        )  
+    {
+        PushLayer(&layerParameters, layer);
+    }
+    
+    void DrawGdiMetafile1() {}
+    
+    void DrawBitmap1() {}
+    void DrawBitmap2() {}
+    void DrawBitmap3() {}
+    
+    void FillOpacityMask1() {}
+    void FillOpacityMask2() {}   
+    
+    //
+    // Sets tuning parameters for internal rendering inside the device context.
+    //
+    void SetRenderingControls1() {}
+}; // interface ID2D1DeviceContext
+
+#endif // #ifndef _D2D1_1_H_