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