1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
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/. */
5 
6 #ifndef GFX_WINDOWS_PLATFORM_H
7 #define GFX_WINDOWS_PLATFORM_H
8 
9 /**
10  * XXX to get CAIRO_HAS_DWRITE_FONT
11  * and cairo_win32_scaled_font_select_font
12  */
13 #include "cairo-win32.h"
14 
15 #include "gfxCrashReporterUtils.h"
16 #include "gfxFontUtils.h"
17 #include "gfxWindowsSurface.h"
18 #include "gfxFont.h"
19 #include "gfxDWriteFonts.h"
20 #include "gfxPlatform.h"
21 #include "gfxTelemetry.h"
22 #include "gfxTypes.h"
23 #include "mozilla/Attributes.h"
24 #include "mozilla/Atomics.h"
25 #include "nsTArray.h"
26 
27 #include "mozilla/Mutex.h"
28 #include "mozilla/RefPtr.h"
29 
30 #include <windows.h>
31 #include <objbase.h>
32 
33 #include <dxgi.h>
34 
35 // This header is available in the June 2010 SDK and in the Win8 SDK
36 #include <d3dcommon.h>
37 // Win 8.0 SDK types we'll need when building using older sdks.
38 #if !defined(D3D_FEATURE_LEVEL_11_1)  // defined in the 8.0 SDK only
39 #  define D3D_FEATURE_LEVEL_11_1 static_cast<D3D_FEATURE_LEVEL>(0xb100)
40 #  define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048
41 #  define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096
42 #endif
43 
44 namespace mozilla {
45 namespace gfx {
46 class DrawTarget;
47 class FeatureState;
48 class DeviceManagerDx;
49 }  // namespace gfx
50 namespace layers {
51 class ReadbackManagerD3D11;
52 }
53 }  // namespace mozilla
54 struct IDirect3DDevice9;
55 struct ID3D11Device;
56 struct IDXGIAdapter1;
57 
58 /**
59  * Utility to get a Windows HDC from a Moz2D DrawTarget.  If the DrawTarget is
60  * not backed by a HDC this will get the HDC for the screen device context
61  * instead.
62  */
63 class MOZ_STACK_CLASS DCForMetrics final {
64  public:
65   explicit DCForMetrics();
66 
~DCForMetrics()67   ~DCForMetrics() { ReleaseDC(nullptr, mDC); }
68 
HDC()69   operator HDC() { return mDC; }
70 
71  private:
72   HDC mDC;
73 };
74 
75 // ClearType parameters set by running ClearType tuner
76 struct ClearTypeParameterInfo {
ClearTypeParameterInfoClearTypeParameterInfo77   ClearTypeParameterInfo()
78       : gamma(-1),
79         pixelStructure(-1),
80         clearTypeLevel(-1),
81         enhancedContrast(-1) {}
82 
83   nsString displayName;  // typically just 'DISPLAY1'
84   int32_t gamma;
85   int32_t pixelStructure;
86   int32_t clearTypeLevel;
87   int32_t enhancedContrast;
88 };
89 
90 class gfxWindowsPlatform final : public gfxPlatform {
91   friend class mozilla::gfx::DeviceManagerDx;
92 
93  public:
94   enum TextRenderingMode {
95     TEXT_RENDERING_NO_CLEARTYPE,
96     TEXT_RENDERING_NORMAL,
97     TEXT_RENDERING_GDI_CLASSIC,
98     TEXT_RENDERING_COUNT
99   };
100 
101   gfxWindowsPlatform();
102   virtual ~gfxWindowsPlatform();
GetPlatform()103   static gfxWindowsPlatform* GetPlatform() {
104     return (gfxWindowsPlatform*)gfxPlatform::GetPlatform();
105   }
106 
107   void EnsureDevicesInitialized() override;
108   bool DevicesInitialized() override;
109 
110   bool CreatePlatformFontList() override;
111 
112   virtual already_AddRefed<gfxASurface> CreateOffscreenSurface(
113       const IntSize& aSize, gfxImageFormat aFormat) override;
114 
115   enum RenderMode {
116     /* Use GDI and windows surfaces */
117     RENDER_GDI = 0,
118 
119     /* Use 32bpp image surfaces and call StretchDIBits */
120     RENDER_IMAGE_STRETCH32,
121 
122     /* Use 32bpp image surfaces, and do 32->24 conversion before calling
123        StretchDIBits */
124     RENDER_IMAGE_STRETCH24,
125 
126     /* Use Direct2D rendering */
127     RENDER_DIRECT2D,
128 
129     /* max */
130     RENDER_MODE_MAX
131   };
132 
133   bool IsDirect2DBackend();
134 
135   /**
136    * Updates render mode with relation to the current preferences and
137    * available devices.
138    */
139   void UpdateRenderMode();
140 
141   /**
142    * Verifies a D2D device is present and working, will attempt to create one
143    * it is non-functional or non-existant.
144    *
145    * \param aAttemptForce Attempt to force D2D cairo device creation by using
146    * cairo device creation routines.
147    */
148   void VerifyD2DDevice(bool aAttemptForce);
149 
150   void GetCommonFallbackFonts(uint32_t aCh, Script aRunScript,
151                               eFontPresentation aPresentation,
152                               nsTArray<const char*>& aFontList) override;
153 
154   bool CanUseHardwareVideoDecoding() override;
155 
156   void CompositorUpdated() override;
157 
158   bool DidRenderingDeviceReset(
159       DeviceResetReason* aResetReason = nullptr) override;
160   void SchedulePaintIfDeviceReset() override;
161   void CheckForContentOnlyDeviceReset();
162 
163   mozilla::gfx::BackendType GetContentBackendFor(
164       mozilla::layers::LayersBackend aLayers) override;
165 
166   mozilla::gfx::BackendType GetPreferredCanvasBackend() override;
167 
168   static void GetDLLVersion(char16ptr_t aDLLPath, nsAString& aVersion);
169 
170   // returns ClearType tuning information for each display
171   static void GetCleartypeParams(nsTArray<ClearTypeParameterInfo>& aParams);
172 
173   void FontsPrefsChanged(const char* aPref) override;
174 
175   void SetupClearTypeParams();
176 
DWriteEnabled()177   static inline bool DWriteEnabled() {
178     return !!mozilla::gfx::Factory::GetDWriteFactory();
179   }
DWriteMeasuringMode()180   inline DWRITE_MEASURING_MODE DWriteMeasuringMode() { return mMeasuringMode; }
181 
182   // Note that this may return nullptr, if we encountered an error initializing
183   // the default rendering params.
GetRenderingParams(TextRenderingMode aRenderMode)184   IDWriteRenderingParams* GetRenderingParams(TextRenderingMode aRenderMode) {
185     return mRenderingParams[aRenderMode];
186   }
187 
188  public:
189   bool DwmCompositionEnabled();
190 
191   mozilla::layers::ReadbackManagerD3D11* GetReadbackManager();
192 
193   static bool IsOptimus();
194 
SupportsApzWheelInput()195   bool SupportsApzWheelInput() const override { return true; }
196 
197   // Recreate devices as needed for a device reset. Returns true if a device
198   // reset occurred.
199   bool HandleDeviceReset();
200   void UpdateBackendPrefs();
201 
202   already_AddRefed<mozilla::gfx::VsyncSource> CreateHardwareVsyncSource()
203       override;
204   static mozilla::Atomic<size_t> sD3D11SharedTextures;
205   static mozilla::Atomic<size_t> sD3D9SharedTextures;
206 
SupportsPluginDirectBitmapDrawing()207   bool SupportsPluginDirectBitmapDrawing() override { return true; }
208 
209   static void RecordContentDeviceFailure(
210       mozilla::gfx::TelemetryDeviceCode aDevice);
211 
212   static void InitMemoryReportersForGPUProcess();
213 
214  protected:
AccelerateLayersByDefault()215   bool AccelerateLayersByDefault() override { return true; }
216   void GetAcceleratedCompositorBackends(
217       nsTArray<mozilla::layers::LayersBackend>& aBackends) override;
218   nsTArray<uint8_t> GetPlatformCMSOutputProfileData() override;
219   void GetPlatformDisplayInfo(mozilla::widget::InfoObject& aObj) override;
220 
221   void ImportGPUDeviceData(const mozilla::gfx::GPUDeviceData& aData) override;
222   void ImportContentDeviceData(
223       const mozilla::gfx::ContentDeviceData& aData) override;
224   void BuildContentDeviceData(mozilla::gfx::ContentDeviceData* aOut) override;
225 
226   BackendPrefsData GetBackendPrefs() const override;
227 
228   bool CheckVariationFontSupport() override;
229 
230  protected:
231   RenderMode mRenderMode;
232 
233  private:
234   enum class DwmCompositionStatus : uint32_t {
235     Unknown,
236     Disabled,
237     Enabled,
238   };
239 
240   void Init();
241   void InitAcceleration() override;
242   void InitWebRenderConfig() override;
243 
244   void InitializeDevices();
245   void InitializeD3D11();
246   void InitializeD2D();
247   bool InitDWriteSupport();
248   void InitGPUProcessSupport();
249 
250   void DisableD2D(mozilla::gfx::FeatureStatus aStatus, const char* aMessage,
251                   const nsACString& aFailureId);
252 
253   void InitializeConfig();
254   void InitializeD3D9Config();
255   void InitializeD3D11Config();
256   void InitializeD2DConfig();
257   void InitializeDirectDrawConfig();
258 
259   void RecordStartupTelemetry();
260 
261   RefPtr<IDWriteRenderingParams> mRenderingParams[TEXT_RENDERING_COUNT];
262   DWRITE_MEASURING_MODE mMeasuringMode;
263 
264   RefPtr<mozilla::layers::ReadbackManagerD3D11> mD3D11ReadbackManager;
265   bool mInitializedDevices = false;
266 
267   mozilla::Atomic<DwmCompositionStatus, mozilla::ReleaseAcquire>
268       mDwmCompositionStatus;
269 
270   // Cached contents of the output color profile file
271   nsTArray<uint8_t> mCachedOutputColorProfile;
272 };
273 
274 #endif /* GFX_WINDOWS_PLATFORM_H */
275