gl_context.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  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. #ifndef UI_GL_GL_CONTEXT_H_
  5. #define UI_GL_GL_CONTEXT_H_
  6. #include <map>
  7. #include <memory>
  8. #include <string>
  9. #include "base/atomicops.h"
  10. #include "base/cancelable_callback.h"
  11. #include "base/memory/raw_ptr.h"
  12. #include "base/memory/ref_counted.h"
  13. #include "base/memory/weak_ptr.h"
  14. #include "base/synchronization/atomic_flag.h"
  15. #include "build/build_config.h"
  16. #include "ui/gfx/extension_set.h"
  17. #include "ui/gl/gl_export.h"
  18. #include "ui/gl/gl_implementation_wrapper.h"
  19. #include "ui/gl/gl_share_group.h"
  20. #include "ui/gl/gl_state_restorer.h"
  21. #include "ui/gl/gl_workarounds.h"
  22. #include "ui/gl/gpu_preference.h"
  23. namespace gfx {
  24. class ColorSpace;
  25. } // namespace gfx
  26. namespace gl {
  27. class GLDisplayEGL;
  28. class YUVToRGBConverter;
  29. } // namespace gl
  30. namespace gpu {
  31. class GLContextVirtual;
  32. } // namespace gpu
  33. namespace gl {
  34. struct CurrentGL;
  35. class LogGLApi;
  36. struct DriverGL;
  37. class GLApi;
  38. class GLFence;
  39. class GLSurface;
  40. class GPUTiming;
  41. class GPUTimingClient;
  42. struct GLVersionInfo;
  43. class RealGLApi;
  44. class TraceGLApi;
  45. // Where available, choose a GL context priority for devices that support it.
  46. // Currently this requires the EGL_IMG_context_priority extension that is
  47. // present on Daydream ready Android devices. Default is Medium, and the
  48. // attribute is ignored if the extension is missing.
  49. //
  50. // "High" priority must only be used for special cases with strong realtime
  51. // requirements, it is incompatible with other critical system GL work such as
  52. // the GVR library's asynchronous reprojection for VR viewing. Please avoid
  53. // using it for any GL contexts that may be used during VR presentation,
  54. // see crbug.com/727800.
  55. //
  56. // Instead, consider using "Low" priority for possibly-slow GL work such as
  57. // user WebGL content.
  58. enum ContextPriority {
  59. ContextPriorityLow,
  60. ContextPriorityMedium,
  61. ContextPriorityHigh
  62. };
  63. // Angle allows selecting context virtualization group at context creation time.
  64. // This enum is used to specify the group number to use for a given context.
  65. // Currently all contexts which does not specify any group number are part of
  66. // default angle context virtualization group. DrDc will use below enum to
  67. // become part of different virtualization group.
  68. enum class AngleContextVirtualizationGroup { kDefault = -1, kDrDc = 1 };
  69. struct GL_EXPORT GLContextAttribs {
  70. GLContextAttribs();
  71. GLContextAttribs(const GLContextAttribs& other);
  72. GLContextAttribs(GLContextAttribs&& other);
  73. ~GLContextAttribs();
  74. GLContextAttribs& operator=(const GLContextAttribs& other);
  75. GLContextAttribs& operator=(GLContextAttribs&& other);
  76. GpuPreference gpu_preference = GpuPreference::kLowPower;
  77. bool bind_generates_resource = true;
  78. bool webgl_compatibility_context = false;
  79. bool global_texture_share_group = false;
  80. bool global_semaphore_share_group = false;
  81. bool robust_resource_initialization = false;
  82. bool robust_buffer_access = false;
  83. int client_major_es_version = 3;
  84. int client_minor_es_version = 0;
  85. bool can_skip_validation = false;
  86. // If true, and if supported (for EGL, this requires the robustness
  87. // extension), set the reset notification strategy to lose context on reset.
  88. // This setting can be changed independently of robust_buffer_access.
  89. // (True by default to match previous behavior.)
  90. bool lose_context_on_reset = true;
  91. // If true, EGL_ANGLE_external_context_and_surface extension will be used to
  92. // create ANGLE context from the current native EGL context.
  93. bool angle_create_from_external_context = false;
  94. // If true, an ANGLE external context will be created with
  95. // EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE is true, so when ReleaseCurrent is
  96. // called, ANGLE will restore the GL state of the native EGL context to the
  97. // state when MakeCurrent was previously called.
  98. bool angle_restore_external_context_state = false;
  99. AngleContextVirtualizationGroup angle_context_virtualization_group_number =
  100. AngleContextVirtualizationGroup::kDefault;
  101. ContextPriority context_priority = ContextPriorityMedium;
  102. };
  103. // Encapsulates an OpenGL context, hiding platform specific management.
  104. class GL_EXPORT GLContext : public base::RefCounted<GLContext>,
  105. public base::SupportsWeakPtr<GLContext> {
  106. public:
  107. explicit GLContext(GLShareGroup* share_group);
  108. GLContext(const GLContext&) = delete;
  109. GLContext& operator=(const GLContext&) = delete;
  110. static int32_t TotalGLContexts();
  111. static bool SwitchableGPUsSupported();
  112. // This should be called at most once at GPU process startup time.
  113. // By default, GPU switching is not supported unless this is called.
  114. static void SetSwitchableGPUsSupported();
  115. // Initializes the GL context to be compatible with the given surface. The GL
  116. // context can be made with other surface's of the same type. The compatible
  117. // surface is only needed for certain platforms like WGL and GLX. It
  118. // should be specific for all platforms though.
  119. virtual bool Initialize(GLSurface* compatible_surface,
  120. const GLContextAttribs& attribs) = 0;
  121. // Makes the GL context and a surface current on the current thread.
  122. bool MakeCurrent(GLSurface* surface);
  123. // Releases this GL context and surface as current on the current thread.
  124. virtual void ReleaseCurrent(GLSurface* surface) = 0;
  125. // Returns true if this context and surface is current. Pass a null surface
  126. // if the current surface is not important.
  127. virtual bool IsCurrent(GLSurface* surface) = 0;
  128. // Get the underlying platform specific GL context "handle".
  129. virtual void* GetHandle() = 0;
  130. // Creates a GPUTimingClient class which abstracts various GPU Timing exts.
  131. virtual scoped_refptr<GPUTimingClient> CreateGPUTimingClient() = 0;
  132. // Set the GL workarounds.
  133. void SetGLWorkarounds(const GLWorkarounds& workarounds);
  134. void SetDisabledGLExtensions(const std::string& disabled_gl_extensions);
  135. // Gets the GLStateRestorer for the context.
  136. GLStateRestorer* GetGLStateRestorer();
  137. // Sets the GLStateRestorer for the context (takes ownership).
  138. void SetGLStateRestorer(GLStateRestorer* state_restorer);
  139. // Returns set of extensions. The context must be current.
  140. virtual const gfx::ExtensionSet& GetExtensions() = 0;
  141. // Indicate that it is safe to force this context to switch GPUs, since
  142. // transitioning can cause corruption and hangs (OS X only).
  143. virtual void SetSafeToForceGpuSwitch();
  144. // Attempt to force the context to move to the GPU of its sharegroup. Return
  145. // false only in the event of an unexpected error on the context.
  146. virtual bool ForceGpuSwitchIfNeeded();
  147. // Indicate that the real context switches should unbind the FBO first
  148. // (For an Android work-around only).
  149. virtual void SetUnbindFboOnMakeCurrent();
  150. // Indicate that the context has become visible/invisible. This can be due to
  151. // tab-switching, window minimization, etc.
  152. virtual void SetVisibility(bool visibility) {}
  153. // Returns whether the current context supports the named extension. The
  154. // context must be current.
  155. bool HasExtension(const char* name);
  156. // Returns version info of the underlying GL context. The context must be
  157. // current.
  158. const GLVersionInfo* GetVersionInfo();
  159. GLShareGroup* share_group();
  160. static bool LosesAllContextsOnContextLost();
  161. // Returns the last GLContext made current, virtual or real.
  162. static GLContext* GetCurrent();
  163. // Returns the 'sticky' value of glGetGraphicsResetStatus, if available.
  164. // 'sticky' implies that if glGetGraphicsResetStatus ever returns a value
  165. // other than GL_NO_ERROR, that value is returned until the context is
  166. // destroyed.
  167. // The context must be current.
  168. unsigned int CheckStickyGraphicsResetStatus();
  169. // Make this context current when used for context virtualization.
  170. bool MakeVirtuallyCurrent(GLContext* virtual_context, GLSurface* surface);
  171. // Notify this context that |virtual_context|, that was using us, is
  172. // being released or destroyed.
  173. void OnReleaseVirtuallyCurrent(GLContext* virtual_context);
  174. // Returns the GL version string. The context must be current.
  175. virtual std::string GetGLVersion();
  176. // Returns the GL renderer string. The context must be current.
  177. virtual std::string GetGLRenderer();
  178. // Returns a helper structure to convert the YUV color space |color_space|
  179. // to its associated full-range RGB color space.
  180. virtual YUVToRGBConverter* GetYUVToRGBConverter(
  181. const gfx::ColorSpace& color_space);
  182. // Get the CurrentGL object for this context containing the driver, version
  183. // and API.
  184. CurrentGL* GetCurrentGL();
  185. // Reinitialize the dynamic bindings of this context. Needed when the driver
  186. // may be exposing different extensions compared to when it was initialized.
  187. // TODO(geofflang): Try to make this call uncessessary by pre-loading all
  188. // extension entry points.
  189. void ReinitializeDynamicBindings();
  190. // Forces this context, which must be a virtual context, to be no
  191. // longer considered virtually current. The real context remains
  192. // current.
  193. virtual void ForceReleaseVirtuallyCurrent();
  194. // Indicates that some GL state was modified that was not tracked by virtual
  195. // contexts. Forces full reset from unknown state the next time a virtual
  196. // context is made current.
  197. void DirtyVirtualContextState();
  198. #if defined(USE_EGL)
  199. // Returns GLDisplayEGL this context belongs to if this context is a
  200. // GLContextEGL; returns nullptr otherwise.
  201. virtual GLDisplayEGL* GetGLDisplayEGL();
  202. #endif // USE_EGL
  203. #if BUILDFLAG(IS_APPLE)
  204. // Create a fence for all work submitted to this context so far, and return a
  205. // monotonically increasing handle to it. This returned handle never needs to
  206. // be freed. This method is used to create backpressure to throttle GL work
  207. // on macOS, so that we do not starve CoreAnimation.
  208. virtual uint64_t BackpressureFenceCreate();
  209. // Perform a client-side wait on a previously-created fence.
  210. virtual void BackpressureFenceWait(uint64_t fence);
  211. // Flush the underlying context to avoid crashes due to driver bugs on macOS.
  212. // https://crbug.com/863817
  213. virtual void FlushForDriverCrashWorkaround();
  214. #endif
  215. protected:
  216. virtual ~GLContext();
  217. // Create the GLApi for this context using the provided driver. Creates a
  218. // RealGLApi by default.
  219. virtual GLApi* CreateGLApi(DriverGL* driver);
  220. // Will release the current context when going out of scope, unless canceled.
  221. class ScopedReleaseCurrent {
  222. public:
  223. ScopedReleaseCurrent();
  224. ~ScopedReleaseCurrent();
  225. void Cancel();
  226. private:
  227. bool canceled_;
  228. };
  229. // Sets the GL api to the real hardware API (vs the VirtualAPI)
  230. void BindGLApi();
  231. virtual void SetCurrent(GLSurface* surface);
  232. // Initialize function pointers to functions where the bound version depends
  233. // on GL version or supported extensions. Should be called immediately after
  234. // this context is made current.
  235. void InitializeDynamicBindings();
  236. // Returns the last real (non-virtual) GLContext made current.
  237. static GLContext* GetRealCurrent();
  238. virtual bool MakeCurrentImpl(GLSurface* surface) = 0;
  239. virtual unsigned int CheckStickyGraphicsResetStatusImpl();
  240. virtual void ResetExtensions() = 0;
  241. GLApi* gl_api() { return gl_api_wrapper_->api(); }
  242. #if BUILDFLAG(IS_APPLE)
  243. // Child classes are responsible for calling DestroyBackpressureFences during
  244. // their destruction while a context is current.
  245. bool HasBackpressureFences() const;
  246. void DestroyBackpressureFences();
  247. #endif
  248. private:
  249. friend class base::RefCounted<GLContext>;
  250. // For GetRealCurrent.
  251. friend class gpu::GLContextVirtual;
  252. std::unique_ptr<GLVersionInfo> GenerateGLVersionInfo();
  253. static base::subtle::Atomic32 total_gl_contexts_;
  254. static bool switchable_gpus_supported_;
  255. GLWorkarounds gl_workarounds_;
  256. std::string disabled_gl_extensions_;
  257. bool static_bindings_initialized_ = false;
  258. bool dynamic_bindings_initialized_ = false;
  259. std::unique_ptr<DriverGL> driver_gl_;
  260. std::unique_ptr<GL_IMPL_WRAPPER_TYPE(GL)> gl_api_wrapper_;
  261. std::unique_ptr<CurrentGL> current_gl_;
  262. // Copy of the real API (if one was created) for dynamic initialization
  263. raw_ptr<RealGLApi> real_gl_api_ = nullptr;
  264. scoped_refptr<GLShareGroup> share_group_;
  265. raw_ptr<GLContext> current_virtual_context_ = nullptr;
  266. bool state_dirtied_externally_ = false;
  267. std::unique_ptr<GLStateRestorer> state_restorer_;
  268. std::unique_ptr<GLVersionInfo> version_info_;
  269. // This bit allows us to avoid virtual context state restoration in the case
  270. // where this underlying context becomes lost. https://crbug.com/1061442
  271. bool context_lost_ = false;
  272. #if BUILDFLAG(IS_APPLE)
  273. std::map<uint64_t, std::unique_ptr<GLFence>> backpressure_fences_;
  274. uint64_t next_backpressure_fence_ = 0;
  275. #endif
  276. };
  277. class GL_EXPORT GLContextReal : public GLContext {
  278. public:
  279. explicit GLContextReal(GLShareGroup* share_group);
  280. GLContextReal(const GLContextReal&) = delete;
  281. GLContextReal& operator=(const GLContextReal&) = delete;
  282. scoped_refptr<GPUTimingClient> CreateGPUTimingClient() override;
  283. const gfx::ExtensionSet& GetExtensions() override;
  284. protected:
  285. ~GLContextReal() override;
  286. void ResetExtensions() override;
  287. void SetCurrent(GLSurface* surface) override;
  288. void SetExtensionsFromString(std::string extensions);
  289. const std::string& extension_string() { return extensions_string_; }
  290. private:
  291. std::unique_ptr<GPUTiming> gpu_timing_;
  292. std::string extensions_string_;
  293. gfx::ExtensionSet extensions_;
  294. bool extensions_initialized_ = false;
  295. };
  296. // Wraps GLContext in scoped_refptr and tries to initializes it. Returns a
  297. // scoped_refptr containing the initialized GLContext or nullptr if
  298. // initialization fails.
  299. GL_EXPORT scoped_refptr<GLContext> InitializeGLContext(
  300. scoped_refptr<GLContext> context,
  301. GLSurface* compatible_surface,
  302. const GLContextAttribs& attribs);
  303. } // namespace gl
  304. #endif // UI_GL_GL_CONTEXT_H_