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_PLATFORM_H
7 #define GFX_PLATFORM_H
8 
9 #include "mozilla/FontPropertyTypes.h"
10 #include "mozilla/gfx/Types.h"
11 #include "mozilla/intl/UnicodeScriptCodes.h"
12 #include "nsTArray.h"
13 #include "nsString.h"
14 #include "nsCOMPtr.h"
15 
16 #include "gfxTelemetry.h"
17 #include "gfxTypes.h"
18 #include "gfxSkipChars.h"
19 
20 #include "qcms.h"
21 
22 #include "mozilla/RefPtr.h"
23 #include "GfxInfoCollector.h"
24 
25 #include "mozilla/layers/CompositorTypes.h"
26 #include "mozilla/layers/LayersTypes.h"
27 #include "mozilla/layers/MemoryPressureObserver.h"
28 
29 class gfxASurface;
30 class gfxFont;
31 class gfxFontGroup;
32 struct gfxFontStyle;
33 class gfxUserFontSet;
34 class gfxFontEntry;
35 class gfxPlatformFontList;
36 class gfxTextRun;
37 class nsIURI;
38 class nsAtom;
39 class nsIObserver;
40 class nsPresContext;
41 class SRGBOverrideObserver;
42 class gfxTextPerfMetrics;
43 typedef struct FT_LibraryRec_* FT_Library;
44 
45 namespace mozilla {
46 struct StyleFontFamilyList;
47 class LogModule;
48 namespace layers {
49 class FrameStats;
50 }
51 namespace gfx {
52 class DrawTarget;
53 class SourceSurface;
54 class DataSourceSurface;
55 class ScaledFont;
56 class VsyncSource;
57 class ContentDeviceData;
58 class GPUDeviceData;
59 class FeatureState;
60 
BackendTypeBit(BackendType b)61 inline uint32_t BackendTypeBit(BackendType b) { return 1 << uint8_t(b); }
62 
63 }  // namespace gfx
64 namespace dom {
65 class SystemFontListEntry;
66 class SystemFontList;
67 }  // namespace dom
68 }  // namespace mozilla
69 
70 #define MOZ_PERFORMANCE_WARNING(module, ...)      \
71   do {                                            \
72     if (gfxPlatform::PerfWarnings()) {            \
73       printf_stderr("[" module "] " __VA_ARGS__); \
74     }                                             \
75   } while (0)
76 
77 enum class CMSMode : int32_t {
78   Off = 0,         // No color management
79   All = 1,         // Color manage everything
80   TaggedOnly = 2,  // Color manage tagged Images Only
81   AllCount = 3
82 };
83 
84 enum eGfxLog {
85   // all font enumerations, localized names, fullname/psnames, cmap loads
86   eGfxLog_fontlist = 0,
87   // timing info on font initialization
88   eGfxLog_fontinit = 1,
89   // dump text runs, font matching, system fallback for content
90   eGfxLog_textrun = 2,
91   // dump text runs, font matching, system fallback for chrome
92   eGfxLog_textrunui = 3,
93   // dump cmap coverage data as they are loaded
94   eGfxLog_cmapdata = 4,
95   // text perf data
96   eGfxLog_textperf = 5
97 };
98 
99 // Used during font matching to express a preference, if any, for whether
100 // to use a font that will present a color or monochrome glyph.
101 enum class eFontPresentation : uint8_t {
102   // Character does not have the emoji property, so no special heuristics
103   // apply during font selection.
104   Any = 0,
105   // Character is potentially emoji, but Text-style presentation has been
106   // explicitly requested using VS15.
107   Text = 1,
108   // Character has Emoji-style presentation by default (but an author-
109   // provided webfont will be used even if it is not color).
110   EmojiDefault = 2,
111   // Character explicitly requires Emoji-style presentation due to VS16 or
112   // skin-tone codepoint.
113   EmojiExplicit = 3
114 };
115 
PrefersColor(eFontPresentation aPresentation)116 inline bool PrefersColor(eFontPresentation aPresentation) {
117   return aPresentation >= eFontPresentation::EmojiDefault;
118 }
119 
120 // when searching through pref langs, max number of pref langs
121 const uint32_t kMaxLenPrefLangList = 32;
122 
123 #define UNINITIALIZED_VALUE (-1)
124 
GetBackendName(mozilla::gfx::BackendType aBackend)125 inline const char* GetBackendName(mozilla::gfx::BackendType aBackend) {
126   switch (aBackend) {
127     case mozilla::gfx::BackendType::DIRECT2D:
128       return "direct2d";
129     case mozilla::gfx::BackendType::CAIRO:
130       return "cairo";
131     case mozilla::gfx::BackendType::SKIA:
132       return "skia";
133     case mozilla::gfx::BackendType::RECORDING:
134       return "recording";
135     case mozilla::gfx::BackendType::DIRECT2D1_1:
136       return "direct2d 1.1";
137     case mozilla::gfx::BackendType::WEBRENDER_TEXT:
138       return "webrender text";
139     case mozilla::gfx::BackendType::NONE:
140       return "none";
141     case mozilla::gfx::BackendType::WEBGL:
142       return "webgl";
143     case mozilla::gfx::BackendType::BACKEND_LAST:
144       return "invalid";
145   }
146   MOZ_CRASH("Incomplete switch");
147 }
148 
149 enum class DeviceResetReason {
150   OK = 0,        // No reset.
151   HUNG,          // Windows specific, guilty device reset.
152   REMOVED,       // Windows specific, device removed or driver upgraded.
153   RESET,         // Guilty device reset.
154   DRIVER_ERROR,  // Innocent device reset.
155   INVALID_CALL,  // Windows specific, guilty device reset.
156   OUT_OF_MEMORY,
157   FORCED_RESET,  // Simulated device reset.
158   OTHER,         // Unrecognized reason for device reset.
159   D3D9_RESET,    // Windows specific, not used.
160   NVIDIA_VIDEO,  // Linux specific, NVIDIA video memory was reset.
161   UNKNOWN,       // GL specific, unknown if guilty or innocent.
162 };
163 
164 enum class ForcedDeviceResetReason {
165   OPENSHAREDHANDLE = 0,
166   COMPOSITOR_UPDATED,
167 };
168 
169 struct BackendPrefsData {
170   uint32_t mCanvasBitmask = 0;
171   mozilla::gfx::BackendType mCanvasDefault = mozilla::gfx::BackendType::NONE;
172   uint32_t mContentBitmask = 0;
173   mozilla::gfx::BackendType mContentDefault = mozilla::gfx::BackendType::NONE;
174 };
175 
176 class gfxPlatform : public mozilla::layers::MemoryPressureListener {
177   friend class SRGBOverrideObserver;
178 
179  public:
180   typedef mozilla::StretchRange StretchRange;
181   typedef mozilla::SlantStyleRange SlantStyleRange;
182   typedef mozilla::WeightRange WeightRange;
183   typedef mozilla::gfx::sRGBColor sRGBColor;
184   typedef mozilla::gfx::DeviceColor DeviceColor;
185   typedef mozilla::gfx::DataSourceSurface DataSourceSurface;
186   typedef mozilla::gfx::DrawTarget DrawTarget;
187   typedef mozilla::gfx::IntSize IntSize;
188   typedef mozilla::gfx::SourceSurface SourceSurface;
189   typedef mozilla::intl::Script Script;
190 
191   /**
192    * Return a pointer to the current active platform.
193    * This is a singleton; it contains mostly convenience
194    * functions to obtain platform-specific objects.
195    */
196   static gfxPlatform* GetPlatform();
197 
198   /**
199    * Returns whether or not graphics has been initialized yet. This is
200    * intended for Telemetry where we don't necessarily want to initialize
201    * graphics just to observe its state.
202    */
203   static bool Initialized();
204 
205   /**
206    * Shut down Thebes.
207    * Init() arranges for this to be called at an appropriate time.
208    */
209   static void Shutdown();
210 
211   /**
212    * Initialize gfxPlatform (if not already done) in a child process, with
213    * the provided ContentDeviceData.
214    */
215   static void InitChild(const mozilla::gfx::ContentDeviceData& aData);
216 
217   static void InitLayersIPC();
218   static void ShutdownLayersIPC();
219 
220   /**
221    * Initialize ScrollMetadata statics. Does not depend on gfxPlatform.
222    */
223   static void InitNullMetadata();
224 
225   static int32_t MaxTextureSize();
226   static int32_t MaxAllocSize();
227   static void InitMoz2DLogging();
228 
229   static bool IsHeadless();
230 
231   static bool UseWebRender();
232 
233   static bool UseRemoteCanvas();
234 
235   static bool IsBackendAccelerated(
236       const mozilla::gfx::BackendType aBackendType);
237 
238   static bool CanMigrateMacGPUs();
239 
240   /**
241    * Create an offscreen surface of the given dimensions
242    * and image format.
243    */
244   virtual already_AddRefed<gfxASurface> CreateOffscreenSurface(
245       const IntSize& aSize, gfxImageFormat aFormat) = 0;
246 
247   /**
248    * Beware that this method may return DrawTargets which are not fully
249    * supported on the current platform and might fail silently in subtle ways.
250    * This is a massive potential footgun. You should only use these methods for
251    * canvas drawing really. Use extreme caution if you use them for content
252    * where you are not 100% sure we support the DrawTarget we get back. See
253    * SupportsAzureContentForDrawTarget.
254    */
255   static already_AddRefed<DrawTarget> CreateDrawTargetForSurface(
256       gfxASurface* aSurface, const mozilla::gfx::IntSize& aSize);
257 
258   /*
259    * Creates a SourceSurface for a gfxASurface. This function does no caching,
260    * so the caller should cache the gfxASurface if it will be used frequently.
261    * The returned surface keeps a reference to aTarget, so it is OK to keep the
262    * surface, even if aTarget changes.
263    * aTarget should not keep a reference to the returned surface because that
264    * will cause a cycle.
265    *
266    * This function is static so that it can be accessed from outside the main
267    * process.
268    *
269    * aIsPlugin is used to tell the backend that they can optimize this surface
270    * specifically because it's used for a plugin. This is mostly for Skia.
271    */
272   static already_AddRefed<SourceSurface> GetSourceSurfaceForSurface(
273       RefPtr<mozilla::gfx::DrawTarget> aTarget, gfxASurface* aSurface,
274       bool aIsPlugin = false);
275 
276   static void ClearSourceSurfaceForSurface(gfxASurface* aSurface);
277 
278   static already_AddRefed<DataSourceSurface> GetWrappedDataSourceSurface(
279       gfxASurface* aSurface);
280 
281   already_AddRefed<DrawTarget> CreateOffscreenContentDrawTarget(
282       const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat,
283       bool aFallback = false);
284 
285   already_AddRefed<DrawTarget> CreateOffscreenCanvasDrawTarget(
286       const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat);
287 
288   already_AddRefed<DrawTarget> CreateSimilarSoftwareDrawTarget(
289       DrawTarget* aDT, const IntSize& aSize,
290       mozilla::gfx::SurfaceFormat aFormat);
291 
292   static already_AddRefed<DrawTarget> CreateDrawTargetForData(
293       unsigned char* aData, const mozilla::gfx::IntSize& aSize, int32_t aStride,
294       mozilla::gfx::SurfaceFormat aFormat, bool aUninitialized = false);
295 
296   /**
297    * Returns true if we should use Azure to render content with aTarget. For
298    * example, it is possible that we are using Direct2D for rendering and thus
299    * using Azure. But we want to render to a CairoDrawTarget, in which case
300    * SupportsAzureContent will return true but SupportsAzureContentForDrawTarget
301    * will return false.
302    */
303   bool SupportsAzureContentForDrawTarget(mozilla::gfx::DrawTarget* aTarget);
304 
SupportsAzureContentForType(mozilla::gfx::BackendType aType)305   bool SupportsAzureContentForType(mozilla::gfx::BackendType aType) {
306     return BackendTypeBit(aType) & mContentBackendBitmask;
307   }
308 
309   static bool AsyncPanZoomEnabled();
310 
311   const char* GetAzureCanvasBackend() const;
312   const char* GetAzureContentBackend() const;
313 
314   void GetAzureBackendInfo(mozilla::widget::InfoObject& aObj);
315   void GetApzSupportInfo(mozilla::widget::InfoObject& aObj);
316   void GetFrameStats(mozilla::widget::InfoObject& aObj);
317   void GetCMSSupportInfo(mozilla::widget::InfoObject& aObj);
318   void GetDisplayInfo(mozilla::widget::InfoObject& aObj);
319 
320   // Get the default content backend that will be used with the default
321   // compositor. If the compositor is known when calling this function,
322   // GetContentBackendFor() should be called instead.
GetDefaultContentBackend()323   mozilla::gfx::BackendType GetDefaultContentBackend() const {
324     return mContentBackend;
325   }
326 
327   /// Return the software backend to use by default.
GetSoftwareBackend()328   mozilla::gfx::BackendType GetSoftwareBackend() { return mSoftwareBackend; }
329 
330   // Return the best content backend available that is compatible with the
331   // given layers backend.
GetContentBackendFor(mozilla::layers::LayersBackend aLayers)332   virtual mozilla::gfx::BackendType GetContentBackendFor(
333       mozilla::layers::LayersBackend aLayers) {
334     return mContentBackend;
335   }
336 
GetPreferredCanvasBackend()337   virtual mozilla::gfx::BackendType GetPreferredCanvasBackend() {
338     return mPreferredCanvasBackend;
339   }
GetFallbackCanvasBackend()340   mozilla::gfx::BackendType GetFallbackCanvasBackend() {
341     return mFallbackCanvasBackend;
342   }
343 
344   /*
345    * Font bits
346    */
347 
348   /**
349    * Fill aListOfFonts with the results of querying the list of font names
350    * that correspond to the given language group or generic font family
351    * (or both, or neither).
352    */
353   virtual nsresult GetFontList(nsAtom* aLangGroup,
354                                const nsACString& aGenericFamily,
355                                nsTArray<nsString>& aListOfFonts);
356 
357   /**
358    * Fill aFontList with a list of SystemFontListEntry records for the
359    * available fonts on the platform; used to pass the list from chrome to
360    * content process. Currently implemented only on MacOSX and Linux.
361    */
ReadSystemFontList(mozilla::dom::SystemFontList *)362   virtual void ReadSystemFontList(mozilla::dom::SystemFontList*){};
363 
364   /**
365    * Rebuilds the system font lists (if aFullRebuild is true), or just notifies
366    * content that the list has changed but existing memory mappings are still
367    * valid (aFullRebuild is false).
368    */
369   nsresult UpdateFontList(bool aFullRebuild = true);
370 
371   /**
372    * Create the platform font-list object (gfxPlatformFontList concrete
373    * subclass). This function is responsible to create the appropriate subclass
374    * of gfxPlatformFontList *and* to call its InitFontList() method.
375    */
376   virtual bool CreatePlatformFontList() = 0;
377 
378   /**
379    * Resolving a font name to family name. The result MUST be in the result of
380    * GetFontList(). If the name doesn't in the system, aFamilyName will be empty
381    * string, but not failed.
382    */
383   void GetStandardFamilyName(const nsCString& aFontName,
384                              nsACString& aFamilyName);
385 
386   /**
387    * Returns default font name (localized family name) for aLangGroup and
388    * aGenericFamily.  The result is typically the first font in
389    * font.name-list.<aGenericFamily>.<aLangGroup>.  However, if it's not
390    * available in the system, this may return second or later font in the
391    * pref.  If there are no available fonts in the pref, returns empty string.
392    */
393   nsAutoCString GetDefaultFontName(const nsACString& aLangGroup,
394                                    const nsACString& aGenericFamily);
395 
396   /**
397    * Create a gfxFontGroup based on the given family list and style.
398    */
399   gfxFontGroup* CreateFontGroup(
400       nsPresContext* aPresContext,
401       const mozilla::StyleFontFamilyList& aFontFamilyList,
402       const gfxFontStyle* aStyle, nsAtom* aLanguage, bool aExplicitLanguage,
403       gfxTextPerfMetrics* aTextPerf, gfxUserFontSet* aUserFontSet,
404       gfxFloat aDevToCssSize) const;
405 
406   /**
407    * Look up a local platform font using the full font face name.
408    * (Needed to support @font-face src local().)
409    * Ownership of the returned gfxFontEntry is passed to the caller,
410    * who must either AddRef() or delete.
411    */
412   gfxFontEntry* LookupLocalFont(nsPresContext* aPresContext,
413                                 const nsACString& aFontName,
414                                 WeightRange aWeightForEntry,
415                                 StretchRange aStretchForEntry,
416                                 SlantStyleRange aStyleForEntry);
417 
418   /**
419    * Activate a platform font.  (Needed to support @font-face src url().)
420    * aFontData is a NS_Malloc'ed block that must be freed by this function
421    * (or responsibility passed on) when it is no longer needed; the caller
422    * will NOT free it.
423    * Ownership of the returned gfxFontEntry is passed to the caller,
424    * who must either AddRef() or delete.
425    */
426   gfxFontEntry* MakePlatformFont(const nsACString& aFontName,
427                                  WeightRange aWeightForEntry,
428                                  StretchRange aStretchForEntry,
429                                  SlantStyleRange aStyleForEntry,
430                                  const uint8_t* aFontData, uint32_t aLength);
431 
432   /**
433    * Whether to allow downloadable fonts via @font-face rules
434    */
435   bool DownloadableFontsEnabled();
436 
437   /**
438    * True when hinting should be enabled.  This setting shouldn't
439    * change per gecko process, while the process is live.  If so the
440    * results are not defined.
441    *
442    * NB: this bit is only honored by the FT2 backend, currently.
443    */
FontHintingEnabled()444   virtual bool FontHintingEnabled() { return true; }
445 
446   /**
447    * True when zooming should not require reflow, so glyph metrics and
448    * positioning should not be adjusted for device pixels.
449    * If this is TRUE, then FontHintingEnabled() should be FALSE,
450    * but the converse is not necessarily required;
451    *
452    * Like FontHintingEnabled (above), this setting shouldn't
453    * change per gecko process, while the process is live.  If so the
454    * results are not defined.
455    *
456    * NB: this bit is only honored by the FT2 backend, currently.
457    */
RequiresLinearZoom()458   virtual bool RequiresLinearZoom() { return false; }
459 
460   /**
461    * Whether the frame->StyleFont().mFont.smoothing field is respected by
462    * text rendering on this platform.
463    */
RespectsFontStyleSmoothing()464   virtual bool RespectsFontStyleSmoothing() const { return false; }
465 
466   /**
467    * Whether to check all font cmaps during system font fallback
468    */
469   bool UseCmapsDuringSystemFallback();
470 
471   /**
472    * Whether to render SVG glyphs within an OpenType font wrapper
473    */
474   bool OpenTypeSVGEnabled();
475 
476   /**
477    * Max character length of words in the word cache
478    */
479   uint32_t WordCacheCharLimit();
480 
481   /**
482    * Max number of entries in word cache
483    */
484   uint32_t WordCacheMaxEntries();
485 
486   /**
487    * Whether to use the SIL Graphite rendering engine
488    * (for fonts that include Graphite tables)
489    */
490   bool UseGraphiteShaping();
491 
492   // Check whether format is supported on a platform (if unclear, returns true).
493   // Default implementation checks for "common" formats that we support across
494   // all platforms, but individual platform implementations may override.
495   virtual bool IsFontFormatSupported(uint32_t aFormatFlags);
496 
497   virtual bool DidRenderingDeviceReset(
498       DeviceResetReason* aResetReason = nullptr) {
499     return false;
500   }
501 
502   // returns a list of commonly used fonts for a given character
503   // these are *possible* matches, no cmap-checking is done at this level
GetCommonFallbackFonts(uint32_t,Script,eFontPresentation,nsTArray<const char * > &)504   virtual void GetCommonFallbackFonts(uint32_t /*aCh*/, Script /*aRunScript*/,
505                                       eFontPresentation /*aPresentation*/,
506                                       nsTArray<const char*>& /*aFontList*/) {
507     // platform-specific override, by default do nothing
508   }
509 
510   // Are we in safe mode?
511   static bool InSafeMode();
512 
513   static bool OffMainThreadCompositingEnabled();
514 
515   void UpdateCanUseHardwareVideoDecoding();
516 
517   /**
518    * Are we going to try color management?
519    */
GetCMSMode()520   static CMSMode GetCMSMode() {
521     EnsureCMSInitialized();
522     return gCMSMode;
523   }
524 
525   /**
526    * Used only for testing. Override the pref setting.
527    */
528   static void SetCMSModeOverride(CMSMode aMode);
529 
530   /**
531    * Determines the rendering intent for color management.
532    *
533    * If the value in the pref gfx.color_management.rendering_intent is a
534    * valid rendering intent as defined in gfx/qcms/qcms.h, that
535    * value is returned. Otherwise, -1 is returned and the embedded intent
536    * should be used.
537    *
538    * See bug 444014 for details.
539    */
540   static int GetRenderingIntent();
541 
542   /**
543    * Convert a pixel using a cms transform in an endian-aware manner.
544    */
545   static DeviceColor TransformPixel(const sRGBColor& in,
546                                     qcms_transform* transform);
547 
548   /**
549    * Return the output device ICC profile.
550    */
GetCMSOutputProfile()551   static qcms_profile* GetCMSOutputProfile() {
552     EnsureCMSInitialized();
553     return gCMSOutputProfile;
554   }
555 
556   /**
557    * Return the sRGB ICC profile.
558    */
GetCMSsRGBProfile()559   static qcms_profile* GetCMSsRGBProfile() {
560     EnsureCMSInitialized();
561     return gCMSsRGBProfile;
562   }
563 
564   /**
565    * Return sRGB -> output device transform.
566    */
GetCMSRGBTransform()567   static qcms_transform* GetCMSRGBTransform() {
568     EnsureCMSInitialized();
569     return gCMSRGBTransform;
570   }
571 
572   /**
573    * Return output -> sRGB device transform.
574    */
GetCMSInverseRGBTransform()575   static qcms_transform* GetCMSInverseRGBTransform() {
576     MOZ_ASSERT(gCMSInitialized);
577     return gCMSInverseRGBTransform;
578   }
579 
580   /**
581    * Return sRGBA -> output device transform.
582    */
GetCMSRGBATransform()583   static qcms_transform* GetCMSRGBATransform() {
584     MOZ_ASSERT(gCMSInitialized);
585     return gCMSRGBATransform;
586   }
587 
588   /**
589    * Return sBGRA -> output device transform.
590    */
GetCMSBGRATransform()591   static qcms_transform* GetCMSBGRATransform() {
592     MOZ_ASSERT(gCMSInitialized);
593     return gCMSBGRATransform;
594   }
595 
596   /**
597    * Return OS RGBA -> output device transform.
598    */
599   static qcms_transform* GetCMSOSRGBATransform();
600 
601   /**
602    * Return OS RGBA QCMS type.
603    */
604   static qcms_data_type GetCMSOSRGBAType();
605 
606   virtual void FontsPrefsChanged(const char* aPref);
607 
608   int32_t GetBidiNumeralOption();
609 
610   /**
611    * Force all presContexts to reflow (and reframe if needed).
612    *
613    * This is used when something about platform settings changes that might have
614    * an effect on layout, such as font rendering settings that influence
615    * metrics, or installed fonts.
616    *
617    * By default it also broadcast it to child processes, but some callers might
618    * not need it if they implement their own notification.
619    */
620   enum class NeedsReframe : bool { No, Yes };
621   enum class BroadcastToChildren : bool { No, Yes };
622   static void ForceGlobalReflow(NeedsReframe,
623                                 BroadcastToChildren = BroadcastToChildren::Yes);
624 
625   static void FlushFontAndWordCaches();
626 
627   /**
628    * Returns a 1x1 DrawTarget that can be used for measuring text etc. as
629    * it would measure if rendered on-screen.  Guaranteed to return a
630    * non-null and valid DrawTarget.
631    */
632   RefPtr<mozilla::gfx::DrawTarget> ScreenReferenceDrawTarget();
633 
634   virtual mozilla::gfx::SurfaceFormat Optimal2DFormatForContent(
635       gfxContentType aContent);
636 
637   virtual gfxImageFormat OptimalFormatForContent(gfxContentType aContent);
638 
GetOffscreenFormat()639   virtual gfxImageFormat GetOffscreenFormat() {
640     return mozilla::gfx::SurfaceFormat::X8R8G8B8_UINT32;
641   }
642 
643   /**
644    * Returns a logger if one is available and logging is enabled
645    */
646   static mozilla::LogModule* GetLog(eGfxLog aWhichLog);
647 
GetScreenDepth()648   int GetScreenDepth() const { return mScreenDepth; }
GetScreenSize()649   mozilla::gfx::IntSize GetScreenSize() const { return mScreenSize; }
650 
651   static void PurgeSkiaFontCache();
652 
653   static bool UsesOffMainThreadCompositing();
654 
655   /**
656    * Get the hardware vsync source for each platform.
657    * Should only exist and be valid on the parent process
658    */
GetHardwareVsync()659   virtual mozilla::gfx::VsyncSource* GetHardwareVsync() {
660     MOZ_ASSERT(mVsyncSource != nullptr);
661     MOZ_ASSERT(XRE_IsParentProcess());
662     return mVsyncSource;
663   }
664 
665   /**
666    * True if layout rendering should use ASAP mode, which means
667    * the refresh driver and compositor should render ASAP.
668    * Used for talos testing purposes
669    */
670   static bool IsInLayoutAsapMode();
671 
672   /**
673    * Returns whether or not a custom vsync rate is set.
674    */
675   static bool ForceSoftwareVsync();
676 
677   /**
678    * Returns the software vsync rate to use.
679    */
680   static int GetSoftwareVsyncRate();
681 
682   /**
683    * Returns the default frame rate for the refresh driver / software vsync.
684    */
685   static int GetDefaultFrameRate();
686 
687   /**
688    * Update the frame rate (called e.g. after pref changes).
689    */
690   static void ReInitFrameRate();
691 
692   /**
693    * Update force subpixel AA quality setting (called after pref
694    * changes).
695    */
696   void UpdateForceSubpixelAAWherePossible();
697 
698   /**
699    * Used to test which input types are handled via APZ.
700    */
SupportsApzWheelInput()701   virtual bool SupportsApzWheelInput() const { return false; }
702   bool SupportsApzTouchInput() const;
703   bool SupportsApzDragInput() const;
704   bool SupportsApzKeyboardInput() const;
705   bool SupportsApzAutoscrolling() const;
706   bool SupportsApzZooming() const;
707 
708   // If a device reset has occurred, schedule any necessary paints in the
709   // widget. This should only be used within nsRefreshDriver.
SchedulePaintIfDeviceReset()710   virtual void SchedulePaintIfDeviceReset() {}
711 
712   /**
713    * Helper method, creates a draw target for a specific Azure backend.
714    * Used by CreateOffscreenDrawTarget.
715    */
716   already_AddRefed<DrawTarget> CreateDrawTargetForBackend(
717       mozilla::gfx::BackendType aBackend, const mozilla::gfx::IntSize& aSize,
718       mozilla::gfx::SurfaceFormat aFormat);
719 
720   /**
721    * Wrapper around StaticPrefs::gfx_perf_warnings_enabled().
722    * Extracted into a function to avoid including StaticPrefs_gfx.h from this
723    * file.
724    */
725   static bool PerfWarnings();
726 
727   static void DisableGPUProcess();
728 
729   void NotifyCompositorCreated(mozilla::layers::LayersBackend aBackend);
GetCompositorBackend()730   mozilla::layers::LayersBackend GetCompositorBackend() const {
731     return mCompositorBackend;
732   }
733 
CompositorUpdated()734   virtual void CompositorUpdated() {}
735 
736   // Plugin async drawing support.
SupportsPluginDirectBitmapDrawing()737   virtual bool SupportsPluginDirectBitmapDrawing() { return false; }
738 
739   // Some platforms don't support CompositorOGL in an unaccelerated OpenGL
740   // context. These platforms should return true here.
RequiresAcceleratedGLContextForCompositorOGL()741   virtual bool RequiresAcceleratedGLContextForCompositorOGL() const {
742     return false;
743   }
744 
745   /**
746    * Check the blocklist for a feature. Returns false if the feature is blocked
747    * with an appropriate message and failure ID.
748    * */
749   static bool IsGfxInfoStatusOkay(int32_t aFeature, nsCString* aOutMessage,
750                                   nsCString& aFailureId);
751 
EmptySkipChars()752   const gfxSkipChars& EmptySkipChars() const { return kEmptySkipChars; }
753 
754   /**
755    * Returns a buffer containing the CMS output profile data. The way this
756    * is obtained is platform-specific.
757    */
758   virtual nsTArray<uint8_t> GetPlatformCMSOutputProfileData();
759 
760   /**
761    * Return information on how child processes should initialize graphics
762    * devices.
763    */
764   virtual void BuildContentDeviceData(mozilla::gfx::ContentDeviceData* aOut);
765 
766   /**
767    * Imports settings from the GPU process. This should only be called through
768    * GPUProcessManager, in the UI process.
769    */
770   virtual void ImportGPUDeviceData(const mozilla::gfx::GPUDeviceData& aData);
771 
HasVariationFontSupport()772   bool HasVariationFontSupport() const { return mHasVariationFontSupport; }
773 
HasNativeColrFontSupport()774   bool HasNativeColrFontSupport() const { return mHasNativeColrFontSupport; }
775 
776   // you probably want to use gfxVars::UseWebRender() instead of this
777   static bool WebRenderPrefEnabled();
778   // you probably want to use gfxVars::UseWebRender() instead of this
779   static bool WebRenderEnvvarEnabled();
780 
781   static const char* WebRenderResourcePathOverride();
782 
783   // Returns true if we would like to keep the GPU process if possible.
784   static bool FallbackFromAcceleration(mozilla::gfx::FeatureStatus aStatus,
785                                        const char* aMessage,
786                                        const nsACString& aFailureId);
787 
788   void NotifyFrameStats(nsTArray<mozilla::layers::FrameStats>&& aFrameStats);
789 
790   virtual void OnMemoryPressure(
791       mozilla::layers::MemoryPressureReason aWhy) override;
792 
EnsureDevicesInitialized()793   virtual void EnsureDevicesInitialized(){};
DevicesInitialized()794   virtual bool DevicesInitialized() { return true; };
795 
IsWaylandDisplay()796   virtual bool IsWaylandDisplay() { return false; }
797 
798   static uint32_t TargetFrameRate();
799 
800   static bool UseDesktopZoomingScrollbars();
801 
802  protected:
803   gfxPlatform();
804   virtual ~gfxPlatform();
805 
806   virtual void InitAcceleration();
807   virtual void InitWebRenderConfig();
808   virtual void InitWebGLConfig();
809   virtual void InitWebGPUConfig();
810   virtual void InitWindowOcclusionConfig();
811 
GetPlatformDisplayInfo(mozilla::widget::InfoObject & aObj)812   virtual void GetPlatformDisplayInfo(mozilla::widget::InfoObject& aObj) {}
813 
814   /**
815    * Called immediately before deleting the gfxPlatform object.
816    */
817   virtual void WillShutdown();
818 
819   /**
820    * Initialized hardware vsync based on each platform.
821    */
822   virtual already_AddRefed<mozilla::gfx::VsyncSource>
823   CreateHardwareVsyncSource();
824 
825   // Returns whether or not layers should be accelerated by default on this
826   // platform.
827   virtual bool AccelerateLayersByDefault();
828 
829   // Returns preferences of canvas and content backends.
830   virtual BackendPrefsData GetBackendPrefs() const;
831 
832   /**
833    * Initialise the preferred and fallback canvas backends
834    * aBackendBitmask specifies the backends which are acceptable to the caller.
835    * The backend used is determined by aBackendBitmask and the order specified
836    * by the gfx.canvas.azure.backends pref.
837    */
838   void InitBackendPrefs(BackendPrefsData&& aPrefsData);
839 
840   /**
841    * Content-process only. Requests device preferences from the parent process
842    * and updates any cached settings.
843    */
844   void FetchAndImportContentDeviceData();
845   virtual void ImportContentDeviceData(
846       const mozilla::gfx::ContentDeviceData& aData);
847 
848   /**
849    * Returns the contents of the file pointed to by the
850    * gfx.color_management.display_profile pref, if set.
851    * Returns an empty array if not set, or if an error occurs
852    */
853   nsTArray<uint8_t> GetPrefCMSOutputProfileData();
854 
855   /**
856    * If inside a child process and currently being initialized by the
857    * SetXPCOMProcessAttributes message, this can be used by subclasses to
858    * retrieve the ContentDeviceData passed by the message
859    *
860    * If not currently being initialized, will return nullptr. In this case,
861    * child should send a sync message to ask parent for color profile
862    */
863   const mozilla::gfx::ContentDeviceData* GetInitContentDeviceData();
864 
865   /**
866    * Increase the global device counter after a device has been removed/reset.
867    */
868   void BumpDeviceCounter();
869 
870   /**
871    * returns the first backend named in the pref gfx.canvas.azure.backends
872    * which is a component of aBackendBitmask, a bitmask of backend types
873    */
874   static mozilla::gfx::BackendType GetCanvasBackendPref(
875       uint32_t aBackendBitmask);
876 
877   /**
878    * returns the first backend named in the pref gfx.content.azure.backend
879    * which is a component of aBackendBitmask, a bitmask of backend types
880    */
881   static mozilla::gfx::BackendType GetContentBackendPref(
882       uint32_t& aBackendBitmask);
883 
884   /**
885    * Will return the first backend named in aBackendPrefName
886    * allowed by aBackendBitmask, a bitmask of backend types.
887    * It also modifies aBackendBitmask to only include backends that are
888    * allowed given the prefs.
889    */
890   static mozilla::gfx::BackendType GetBackendPref(const char* aBackendPrefName,
891                                                   uint32_t& aBackendBitmask);
892   /**
893    * Decode the backend enumberation from a string.
894    */
895   static mozilla::gfx::BackendType BackendTypeForName(const nsCString& aName);
896 
897   virtual bool CanUseHardwareVideoDecoding();
898 
899   virtual bool CheckVariationFontSupport() = 0;
900 
901   int8_t mAllowDownloadableFonts;
902   int8_t mGraphiteShapingEnabled;
903   int8_t mOpenTypeSVGEnabled;
904 
905   int8_t mBidiNumeralOption;
906 
907   // whether to always search font cmaps globally
908   // when doing system font fallback
909   int8_t mFallbackUsesCmaps;
910 
911   // Whether the platform supports rendering OpenType font variations
912   bool mHasVariationFontSupport;
913 
914   // Whether the platform font APIs have native support for COLR fonts.
915   // Set to true during initialization on platforms that implement this.
916   bool mHasNativeColrFontSupport = false;
917 
918   // max character limit for words in word cache
919   int32_t mWordCacheCharLimit;
920 
921   // max number of entries in word cache
922   int32_t mWordCacheMaxEntries;
923 
924   // Hardware vsync source. Only valid on parent process
925   RefPtr<mozilla::gfx::VsyncSource> mVsyncSource;
926 
927   RefPtr<mozilla::gfx::DrawTarget> mScreenReferenceDrawTarget;
928 
929  private:
930   /**
931    * Start up Thebes.
932    */
933   static void Init();
934 
935   static void InitOpenGLConfig();
936 
937   static mozilla::Atomic<bool, mozilla::MemoryOrdering::ReleaseAcquire>
938       gCMSInitialized;
939   static CMSMode gCMSMode;
940 
941   // These two may point to the same profile
942   static qcms_profile* gCMSOutputProfile;
943   static qcms_profile* gCMSsRGBProfile;
944 
945   static qcms_transform* gCMSRGBTransform;
946   static qcms_transform* gCMSInverseRGBTransform;
947   static qcms_transform* gCMSRGBATransform;
948   static qcms_transform* gCMSBGRATransform;
949 
EnsureCMSInitialized()950   inline static void EnsureCMSInitialized() {
951     if (MOZ_UNLIKELY(!gCMSInitialized)) {
952       InitializeCMS();
953     }
954   }
955 
956   static void InitializeCMS();
957   static void ShutdownCMS();
958 
959   /**
960    * This uses nsIScreenManager to determine the screen size and color depth
961    */
962   void PopulateScreenInfo();
963 
964   void InitCompositorAccelerationPrefs();
965   void InitGPUProcessPrefs();
InitPlatformGPUProcessPrefs()966   virtual void InitPlatformGPUProcessPrefs() {}
967 
968   // Gather telemetry data about the Gfx Platform and send it
969   static void ReportTelemetry();
970 
971   static bool IsDXInterop2Blocked();
972   static bool IsDXNV12Blocked();
973   static bool IsDXP010Blocked();
974   static bool IsDXP016Blocked();
975 
976   RefPtr<gfxASurface> mScreenReferenceSurface;
977   RefPtr<mozilla::layers::MemoryPressureObserver> mMemoryPressureObserver;
978 
979   // The preferred draw target backend to use for canvas
980   mozilla::gfx::BackendType mPreferredCanvasBackend;
981   // The fallback draw target backend to use for canvas, if the preferred
982   // backend fails
983   mozilla::gfx::BackendType mFallbackCanvasBackend;
984   // The backend to use for content
985   mozilla::gfx::BackendType mContentBackend;
986   // The backend to use when we need it not to be accelerated.
987   mozilla::gfx::BackendType mSoftwareBackend;
988   // Bitmask of backend types we can use to render content
989   uint32_t mContentBackendBitmask;
990 
991   mozilla::widget::GfxInfoCollector<gfxPlatform> mAzureCanvasBackendCollector;
992   mozilla::widget::GfxInfoCollector<gfxPlatform> mApzSupportCollector;
993   mozilla::widget::GfxInfoCollector<gfxPlatform> mFrameStatsCollector;
994   mozilla::widget::GfxInfoCollector<gfxPlatform> mCMSInfoCollector;
995   mozilla::widget::GfxInfoCollector<gfxPlatform> mDisplayInfoCollector;
996 
997   nsTArray<mozilla::layers::FrameStats> mFrameStats;
998 
999   // Backend that we are compositing with. NONE, if no compositor has been
1000   // created yet.
1001   mozilla::layers::LayersBackend mCompositorBackend;
1002 
1003   int32_t mScreenDepth;
1004   mozilla::gfx::IntSize mScreenSize;
1005 
1006   // An instance of gfxSkipChars which is empty. It is used as the
1007   // basis for error-case iterators.
1008   const gfxSkipChars kEmptySkipChars;
1009 };
1010 
1011 #endif /* GFX_PLATFORM_H */
1012