1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef UI_GL_GL_SURFACE_EGL_H_
6 #define UI_GL_GL_SURFACE_EGL_H_
7 
8 #if defined(OS_WIN)
9 #include <windows.h>
10 #endif
11 
12 #include <memory>
13 #include <string>
14 #include <vector>
15 
16 #include "base/command_line.h"
17 #include "base/compiler_specific.h"
18 #include "base/containers/queue.h"
19 #include "base/macros.h"
20 #include "base/time/time.h"
21 #include "build/build_config.h"
22 #include "ui/gfx/geometry/size.h"
23 #include "ui/gfx/vsync_provider.h"
24 #include "ui/gl/egl_timestamps.h"
25 #include "ui/gl/gl_bindings.h"
26 #include "ui/gl/gl_export.h"
27 #include "ui/gl/gl_surface.h"
28 #include "ui/gl/gl_surface_overlay.h"
29 
30 namespace gl {
31 
32 class EGLDisplayPlatform {
33  public:
EGLDisplayPlatform()34   constexpr EGLDisplayPlatform()
35       : display_(EGL_DEFAULT_DISPLAY), platform_(0), valid_(false) {}
36   explicit constexpr EGLDisplayPlatform(EGLNativeDisplayType display,
37                                         int platform = 0)
display_(display)38       : display_(display), platform_(platform), valid_(true) {}
39 
Valid()40   bool Valid() const { return valid_; }
GetPlatform()41   int GetPlatform() const { return platform_; }
GetDisplay()42   EGLNativeDisplayType GetDisplay() const { return display_; }
43 
44  private:
45   EGLNativeDisplayType display_;
46   // 0 for default, or EGL_PLATFORM_* enum.
47   int platform_;
48   bool valid_;
49 };
50 
51 class GLSurfacePresentationHelper;
52 
53 // If adding a new type, also add it to EGLDisplayType in
54 // tools/metrics/histograms/enums.xml. Don't remove or reorder entries.
55 enum DisplayType {
56   DEFAULT = 0,
57   SWIFT_SHADER = 1,
58   ANGLE_WARP = 2,
59   ANGLE_D3D9 = 3,
60   ANGLE_D3D11 = 4,
61   ANGLE_OPENGL = 5,
62   ANGLE_OPENGLES = 6,
63   ANGLE_NULL = 7,
64   ANGLE_D3D11_NULL = 8,
65   ANGLE_OPENGL_NULL = 9,
66   ANGLE_OPENGLES_NULL = 10,
67   ANGLE_VULKAN = 11,
68   ANGLE_VULKAN_NULL = 12,
69   ANGLE_D3D11on12 = 13,
70   ANGLE_SWIFTSHADER = 14,
71   ANGLE_OPENGL_EGL = 15,
72   ANGLE_OPENGLES_EGL = 16,
73   ANGLE_METAL = 17,
74   ANGLE_METAL_NULL = 18,
75   DISPLAY_TYPE_MAX = 19,
76 };
77 
78 GL_EXPORT void GetEGLInitDisplays(bool supports_angle_d3d,
79                                   bool supports_angle_opengl,
80                                   bool supports_angle_null,
81                                   bool supports_angle_vulkan,
82                                   bool supports_angle_swiftshader,
83                                   bool supports_angle_egl,
84                                   bool supports_angle_metal,
85                                   const base::CommandLine* command_line,
86                                   std::vector<DisplayType>* init_displays);
87 
88 // Interface for EGL surface.
89 class GL_EXPORT GLSurfaceEGL : public GLSurface {
90  public:
91   GLSurfaceEGL();
92 
93   // Implement GLSurface.
94   EGLDisplay GetDisplay() override;
95   EGLConfig GetConfig() override;
96   GLSurfaceFormat GetFormat() override;
97 
98   static bool InitializeOneOff(EGLDisplayPlatform native_display);
99   static bool InitializeOneOffForTesting();
100   static bool InitializeExtensionSettingsOneOff();
101   static void ShutdownOneOff();
102   static EGLDisplay GetHardwareDisplay();
103   static EGLDisplay InitializeDisplay(EGLDisplayPlatform native_display);
104   static EGLNativeDisplayType GetNativeDisplay();
105 
106   // These aren't particularly tied to surfaces, but since we already
107   // have the static InitializeOneOff here, it's easiest to reuse its
108   // initialization guards.
109   static const char* GetEGLExtensions();
110   static bool HasEGLExtension(const char* name);
111   static bool IsCreateContextRobustnessSupported();
112   static bool IsRobustnessVideoMemoryPurgeSupported();
113   static bool IsCreateContextBindGeneratesResourceSupported();
114   static bool IsCreateContextWebGLCompatabilitySupported();
115   static bool IsEGLSurfacelessContextSupported();
116   static bool IsEGLContextPrioritySupported();
117   static bool IsEGLFlexibleSurfaceCompatibilitySupported();
118   static bool IsRobustResourceInitSupported();
119   static bool IsDisplayTextureShareGroupSupported();
120   static bool IsDisplaySemaphoreShareGroupSupported();
121   static bool IsCreateContextClientArraysSupported();
122   static bool IsAndroidNativeFenceSyncSupported();
123   static bool IsPixelFormatFloatSupported();
124   static bool IsANGLEFeatureControlSupported();
125   static bool IsANGLEPowerPreferenceSupported();
126 
127  protected:
128   ~GLSurfaceEGL() override;
129 
130   EGLConfig config_ = nullptr;
131   GLSurfaceFormat format_;
132 
133  private:
134   DISALLOW_COPY_AND_ASSIGN(GLSurfaceEGL);
135   static bool InitializeOneOffCommon();
136   static bool initialized_;
137 };
138 
139 // Encapsulates an EGL surface bound to a view.
140 class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL,
141                                          public EGLTimestampClient {
142  public:
143   NativeViewGLSurfaceEGL(EGLNativeWindowType window,
144                          std::unique_ptr<gfx::VSyncProvider> vsync_provider);
145 
146   // Implement GLSurface.
147   bool Initialize(GLSurfaceFormat format) override;
148   bool SupportsSwapTimestamps() const override;
149   void SetEnableSwapTimestamps() override;
150   void Destroy() override;
151   bool Resize(const gfx::Size& size,
152               float scale_factor,
153               const gfx::ColorSpace& color_space,
154               bool has_alpha) override;
155   bool Recreate() override;
156   bool IsOffscreen() override;
157   gfx::SwapResult SwapBuffers(PresentationCallback callback) override;
158   gfx::Size GetSize() override;
159   EGLSurface GetHandle() override;
160   bool SupportsPostSubBuffer() override;
161   gfx::SwapResult PostSubBuffer(int x,
162                                 int y,
163                                 int width,
164                                 int height,
165                                 PresentationCallback callback) override;
166   bool SupportsCommitOverlayPlanes() override;
167   gfx::SwapResult CommitOverlayPlanes(PresentationCallback callback) override;
168   bool OnMakeCurrent(GLContext* context) override;
169   gfx::VSyncProvider* GetVSyncProvider() override;
170   void SetVSyncEnabled(bool enabled) override;
171   bool ScheduleOverlayPlane(int z_order,
172                             gfx::OverlayTransform transform,
173                             GLImage* image,
174                             const gfx::Rect& bounds_rect,
175                             const gfx::RectF& crop_rect,
176                             bool enable_blend,
177                             std::unique_ptr<gfx::GpuFence> gpu_fence) override;
178   gfx::SurfaceOrigin GetOrigin() const override;
179   EGLTimestampClient* GetEGLTimestampClient() override;
180 
181   // EGLTimestampClient implementation.
182   bool IsEGLTimestampSupported() const override;
183 
184   bool GetFrameTimestampInfoIfAvailable(base::TimeTicks* presentation_time,
185                                         base::TimeDelta* composite_interval,
186                                         uint32_t* presentation_flags,
187                                         int frame_id) override;
188 
189   // Takes care of the platform dependant bits, of any, for creating the window.
190   virtual bool InitializeNativeWindow();
191 
192  protected:
193   ~NativeViewGLSurfaceEGL() override;
194 
195   EGLNativeWindowType window_ = 0;
196   gfx::Size size_ = gfx::Size(1, 1);
197   bool enable_fixed_size_angle_ = true;
198 
199   gfx::SwapResult SwapBuffersWithDamage(const std::vector<int>& rects,
200                                         PresentationCallback callback);
201 
202  private:
203   struct SwapInfo {
204     bool frame_id_is_valid;
205     EGLuint64KHR frame_id;
206   };
207 
208   // Commit the |pending_overlays_| and clear the vector. Returns false if any
209   // fail to be committed.
210   bool CommitAndClearPendingOverlays();
211   void UpdateSwapEvents(EGLuint64KHR newFrameId, bool newFrameIdIsValid);
212   void TraceSwapEvents(EGLuint64KHR oldFrameId);
213 
214   // Some platforms may provide a custom implementation of vsync provider.
215   virtual std::unique_ptr<gfx::VSyncProvider> CreateVsyncProviderInternal();
216 
217   EGLSurface surface_ = nullptr;
218   bool supports_post_sub_buffer_ = false;
219   bool supports_swap_buffer_with_damage_ = false;
220   gfx::SurfaceOrigin surface_origin_ = gfx::SurfaceOrigin::kBottomLeft;
221 
222   std::unique_ptr<gfx::VSyncProvider> vsync_provider_external_;
223   std::unique_ptr<gfx::VSyncProvider> vsync_provider_internal_;
224 
225   std::vector<GLSurfaceOverlay> pending_overlays_;
226 
227   // Stored in separate vectors so we can pass the egl timestamps
228   // directly to the EGL functions.
229   bool use_egl_timestamps_ = false;
230   std::vector<EGLint> supported_egl_timestamps_;
231   std::vector<const char*> supported_event_names_;
232 
233   // PresentationFeedback support.
234   int presentation_feedback_index_ = -1;
235   int composition_start_index_ = -1;
236   uint32_t presentation_flags_ = 0;
237 
238   base::queue<SwapInfo> swap_info_queue_;
239 
240   bool vsync_enabled_ = true;
241   std::unique_ptr<GLSurfacePresentationHelper> presentation_helper_;
242 
243   DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceEGL);
244 };
245 
246 // Encapsulates a pbuffer EGL surface.
247 class GL_EXPORT PbufferGLSurfaceEGL : public GLSurfaceEGL {
248  public:
249   explicit PbufferGLSurfaceEGL(const gfx::Size& size);
250 
251   // Implement GLSurface.
252   bool Initialize(GLSurfaceFormat format) override;
253   void Destroy() override;
254   bool IsOffscreen() override;
255   gfx::SwapResult SwapBuffers(PresentationCallback callback) override;
256   gfx::Size GetSize() override;
257   bool Resize(const gfx::Size& size,
258               float scale_factor,
259               const gfx::ColorSpace& color_space,
260               bool has_alpha) override;
261   EGLSurface GetHandle() override;
262   void* GetShareHandle() override;
263 
264  protected:
265   ~PbufferGLSurfaceEGL() override;
266 
267  private:
268   gfx::Size size_;
269   EGLSurface surface_;
270 
271   DISALLOW_COPY_AND_ASSIGN(PbufferGLSurfaceEGL);
272 };
273 
274 // SurfacelessEGL is used as Offscreen surface when platform supports
275 // KHR_surfaceless_context and GL_OES_surfaceless_context. This would avoid the
276 // need to create a dummy EGLsurface in case we render to client API targets.
277 class GL_EXPORT SurfacelessEGL : public GLSurfaceEGL {
278  public:
279   explicit SurfacelessEGL(const gfx::Size& size);
280 
281   // Implement GLSurface.
282   bool Initialize(GLSurfaceFormat format) override;
283   void Destroy() override;
284   bool IsOffscreen() override;
285   bool IsSurfaceless() const override;
286   gfx::SwapResult SwapBuffers(PresentationCallback callback) override;
287   gfx::Size GetSize() override;
288   bool Resize(const gfx::Size& size,
289               float scale_factor,
290               const gfx::ColorSpace& color_space,
291               bool has_alpha) override;
292   EGLSurface GetHandle() override;
293   void* GetShareHandle() override;
294 
295  protected:
296   ~SurfacelessEGL() override;
297 
298  private:
299   gfx::Size size_;
300   DISALLOW_COPY_AND_ASSIGN(SurfacelessEGL);
301 };
302 
303 }  // namespace gl
304 
305 #endif  // UI_GL_GL_SURFACE_EGL_H_
306