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