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_CONTEXT_H_ 6 #define UI_GL_GL_CONTEXT_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/synchronization/cancellation_flag.h" 15 #include "ui/gl/gl_share_group.h" 16 #include "ui/gl/gl_state_restorer.h" 17 #include "ui/gl/gpu_preference.h" 18 19 namespace gfx { 20 21 class GLSurface; 22 class VirtualGLApi; 23 struct GLVersionInfo; 24 25 // Encapsulates an OpenGL context, hiding platform specific management. 26 class GL_EXPORT GLContext : public base::RefCounted<GLContext> { 27 public: 28 explicit GLContext(GLShareGroup* share_group); 29 30 // Initializes the GL context to be compatible with the given surface. The GL 31 // context can be made with other surface's of the same type. The compatible 32 // surface is only needed for certain platforms like WGL, OSMesa and GLX. It 33 // should be specific for all platforms though. 34 virtual bool Initialize( 35 GLSurface* compatible_surface, GpuPreference gpu_preference) = 0; 36 37 class FlushEvent : public base::RefCountedThreadSafe<FlushEvent> { 38 public: 39 bool IsSignaled(); 40 41 private: 42 friend class base::RefCountedThreadSafe<FlushEvent>; 43 friend class GLContext; 44 FlushEvent(); 45 virtual ~FlushEvent(); 46 void Signal(); 47 48 base::CancellationFlag flag_; 49 }; 50 51 // Needs to be called with this context current. It will return a FlushEvent 52 // that is initially unsignaled, but will transition to signaled after the 53 // next glFlush() or glFinish() occurs in this context. 54 scoped_refptr<FlushEvent> SignalFlush(); 55 56 // Destroys the GL context. 57 virtual void Destroy() = 0; 58 59 // Makes the GL context and a surface current on the current thread. 60 virtual bool MakeCurrent(GLSurface* surface) = 0; 61 62 // Releases this GL context and surface as current on the current thread. 63 virtual void ReleaseCurrent(GLSurface* surface) = 0; 64 65 // Returns true if this context and surface is current. Pass a null surface 66 // if the current surface is not important. 67 virtual bool IsCurrent(GLSurface* surface) = 0; 68 69 // Get the underlying platform specific GL context "handle". 70 virtual void* GetHandle() = 0; 71 72 // Gets the GLStateRestorer for the context. 73 GLStateRestorer* GetGLStateRestorer(); 74 75 // Sets the GLStateRestorer for the context (takes ownership). 76 void SetGLStateRestorer(GLStateRestorer* state_restorer); 77 78 // Set swap interval. This context must be current. 79 virtual void SetSwapInterval(int interval) = 0; 80 81 // Returns space separated list of extensions. The context must be current. 82 virtual std::string GetExtensions(); 83 84 // Returns in bytes the total amount of GPU memory for the GPU which this 85 // context is currently rendering on. Returns false if no extension exists 86 // to get the exact amount of GPU memory. 87 virtual bool GetTotalGpuMemory(size_t* bytes); 88 89 // Indicate that it is safe to force this context to switch GPUs, since 90 // transitioning can cause corruption and hangs (OS X only). 91 virtual void SetSafeToForceGpuSwitch(); 92 93 // Indicate that the real context switches should unbind the FBO first 94 // (For an Android work-around only). 95 virtual void SetUnbindFboOnMakeCurrent(); 96 97 // Returns whether the current context supports the named extension. The 98 // context must be current. 99 bool HasExtension(const char* name); 100 101 // Returns version info of the underlying GL context. The context must be 102 // current. 103 const GLVersionInfo* GetVersionInfo(); 104 105 GLShareGroup* share_group(); 106 107 // Create a GL context that is compatible with the given surface. 108 // |share_group|, if non-NULL, is a group of contexts which the 109 // internally created OpenGL context shares textures and other resources. 110 static scoped_refptr<GLContext> CreateGLContext( 111 GLShareGroup* share_group, 112 GLSurface* compatible_surface, 113 GpuPreference gpu_preference); 114 115 static bool LosesAllContextsOnContextLost(); 116 117 // Returns the last GLContext made current, virtual or real. 118 static GLContext* GetCurrent(); 119 120 virtual bool WasAllocatedUsingRobustnessExtension(); 121 122 // Use this context for virtualization. 123 void SetupForVirtualization(); 124 125 // Make this context current when used for context virtualization. 126 bool MakeVirtuallyCurrent(GLContext* virtual_context, GLSurface* surface); 127 128 // Notify this context that |virtual_context|, that was using us, is 129 // being released or destroyed. 130 void OnReleaseVirtuallyCurrent(GLContext* virtual_context); 131 132 // Returns the GL version string. The context must be current. 133 virtual std::string GetGLVersion(); 134 135 // Returns the GL renderer string. The context must be current. 136 virtual std::string GetGLRenderer(); 137 138 // Called when glFlush()/glFinish() is called with this context current. 139 void OnFlush(); 140 141 protected: 142 virtual ~GLContext(); 143 144 // Will release the current context when going out of scope, unless canceled. 145 class ScopedReleaseCurrent { 146 public: 147 ScopedReleaseCurrent(); 148 ~ScopedReleaseCurrent(); 149 150 void Cancel(); 151 152 private: 153 bool canceled_; 154 }; 155 156 // Sets the GL api to the real hardware API (vs the VirtualAPI) 157 static void SetRealGLApi(); 158 virtual void SetCurrent(GLSurface* surface); 159 160 // Initialize function pointers to functions where the bound version depends 161 // on GL version or supported extensions. Should be called immediately after 162 // this context is made current. 163 bool InitializeDynamicBindings(); 164 165 // Returns the last real (non-virtual) GLContext made current. 166 static GLContext* GetRealCurrent(); 167 168 private: 169 friend class base::RefCounted<GLContext>; 170 171 // For GetRealCurrent. 172 friend class VirtualGLApi; 173 174 scoped_refptr<GLShareGroup> share_group_; 175 scoped_ptr<VirtualGLApi> virtual_gl_api_; 176 scoped_ptr<GLStateRestorer> state_restorer_; 177 scoped_ptr<GLVersionInfo> version_info_; 178 179 std::vector<scoped_refptr<FlushEvent> > flush_events_; 180 181 DISALLOW_COPY_AND_ASSIGN(GLContext); 182 }; 183 184 class GL_EXPORT GLContextReal : public GLContext { 185 public: 186 explicit GLContextReal(GLShareGroup* share_group); 187 188 protected: 189 virtual ~GLContextReal(); 190 191 virtual void SetCurrent(GLSurface* surface) OVERRIDE; 192 193 private: 194 DISALLOW_COPY_AND_ASSIGN(GLContextReal); 195 }; 196 197 } // namespace gfx 198 199 #endif // UI_GL_GL_CONTEXT_H_ 200