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_H_ 6 #define UI_GL_GL_SURFACE_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/callback.h" 12 #include "base/macros.h" 13 #include "base/memory/ref_counted.h" 14 #include "build/build_config.h" 15 #include "ui/gfx/geometry/rect.h" 16 #include "ui/gfx/geometry/rect_f.h" 17 #include "ui/gfx/geometry/size.h" 18 #include "ui/gfx/geometry/vector2d.h" 19 #include "ui/gfx/native_widget_types.h" 20 #include "ui/gfx/overlay_transform.h" 21 #include "ui/gfx/presentation_feedback.h" 22 #include "ui/gfx/surface_origin.h" 23 #include "ui/gfx/swap_result.h" 24 #include "ui/gl/gl_export.h" 25 #include "ui/gl/gl_image.h" 26 #include "ui/gl/gl_implementation.h" 27 #include "ui/gl/gl_surface_format.h" 28 29 namespace gfx { 30 class ColorSpace; 31 class GpuFence; 32 class VSyncProvider; 33 } // namespace gfx 34 35 namespace ui { 36 struct CARendererLayerParams; 37 struct DCRendererLayerParams; 38 } // namespace ui 39 40 namespace gl { 41 42 class GLContext; 43 class EGLTimestampClient; 44 45 // Encapsulates a surface that can be rendered to with GL, hiding platform 46 // specific management. 47 class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> { 48 public: 49 GLSurface(); 50 51 // Non-virtual initialization, this always calls Initialize with a 52 // default GLSurfaceFormat. Subclasses should override the format- 53 // specific Initialize method below and interpret the default format 54 // as appropriate. 55 bool Initialize(); 56 57 // (Re)create the surface. TODO(apatrick): This is an ugly hack to allow the 58 // EGL surface associated to be recreated without destroying the associated 59 // context. The implementation of this function for other GLSurface derived 60 // classes is in a pending changelist. 61 virtual bool Initialize(GLSurfaceFormat format); 62 63 // Destroys the surface. 64 virtual void Destroy() = 0; 65 66 // Some implementations (macOS), in Destroy, will need to delete GL objects 67 // that exist in the current GL context. This method is called before the 68 // context's decoder (and potentially context itself) are destroyed, giving an 69 // opportunity for this cleanup. 70 virtual void PrepareToDestroy(bool have_context); 71 72 // Resizes the surface, returning success. If failed, it is possible that the 73 // context is no longer current. 74 virtual bool Resize(const gfx::Size& size, 75 float scale_factor, 76 const gfx::ColorSpace& color_space, 77 bool has_alpha); 78 79 // Recreate the surface without changing the size, returning success. If 80 // failed, it is possible that the context is no longer current. 81 virtual bool Recreate(); 82 83 // Unschedule the CommandExecutor and return true to abort the processing of 84 // a GL draw call to this surface and defer it until the CommandExecutor is 85 // rescheduled. 86 virtual bool DeferDraws(); 87 88 // Returns true if this surface is offscreen. 89 virtual bool IsOffscreen() = 0; 90 91 // The callback is for receiving presentation feedback from |SwapBuffers|, 92 // |PostSubBuffer|, |CommitOverlayPlanes|, etc. 93 // See |PresentationFeedback| for detail. 94 using PresentationCallback = 95 base::OnceCallback<void(const gfx::PresentationFeedback& feedback)>; 96 97 // Swaps front and back buffers. This has no effect for off-screen 98 // contexts. If it returns SWAP_FAILED, it is possible that the context is no 99 // longer current. 100 virtual gfx::SwapResult SwapBuffers(PresentationCallback callback) = 0; 101 102 // Get the size of the surface. 103 virtual gfx::Size GetSize() = 0; 104 105 // Get the underlying platform specific surface "handle". 106 virtual void* GetHandle() = 0; 107 108 // Returns whether or not the surface supports SwapBuffersWithBounds 109 virtual bool SupportsSwapBuffersWithBounds(); 110 111 // Returns whether or not the surface supports PostSubBuffer. 112 virtual bool SupportsPostSubBuffer(); 113 114 // Returns whether or not the surface supports CommitOverlayPlanes. 115 virtual bool SupportsCommitOverlayPlanes(); 116 117 // Returns whether SwapBuffersAsync() is supported. 118 virtual bool SupportsAsyncSwap(); 119 120 // Returns the internal frame buffer object name if the surface is backed by 121 // FBO. Otherwise returns 0. 122 virtual unsigned int GetBackingFramebufferObject(); 123 124 // The SwapCompletionCallback is used to receive notification about the 125 // completion of the swap operation from |SwapBuffersAsync|, 126 // |PostSubBufferAsync|, |CommitOverlayPlanesAsync|, etc. If a null gpu fence 127 // is returned, then the swap is guaranteed to have already completed. If a 128 // non-null gpu fence is returned, then the swap operation may still be in 129 // progress when this callback is invoked, and the signaling of the gpu fence 130 // will mark the completion of the swap operation. 131 using SwapCompletionCallback = 132 base::OnceCallback<void(gfx::SwapResult, std::unique_ptr<gfx::GpuFence>)>; 133 // Swaps front and back buffers. This has no effect for off-screen 134 // contexts. On some platforms, we want to send SwapBufferAck only after the 135 // surface is displayed on screen. The callback can be used to delay sending 136 // SwapBufferAck till that data is available. The callback should be run on 137 // the calling thread (i.e. same thread SwapBuffersAsync is called) 138 virtual void SwapBuffersAsync(SwapCompletionCallback completion_callback, 139 PresentationCallback presentation_callback); 140 141 // Swap buffers with content bounds. If it returns SWAP_FAILED, it is possible 142 // that the context is no longer current. 143 virtual gfx::SwapResult SwapBuffersWithBounds( 144 const std::vector<gfx::Rect>& rects, 145 PresentationCallback callback); 146 147 // Copy part of the backbuffer to the frontbuffer. If it returns SWAP_FAILED, 148 // it is possible that the context is no longer current. 149 virtual gfx::SwapResult PostSubBuffer(int x, 150 int y, 151 int width, 152 int height, 153 PresentationCallback callback); 154 155 // Copy part of the backbuffer to the frontbuffer. On some platforms, we want 156 // to send SwapBufferAck only after the surface is displayed on screen. The 157 // callback can be used to delay sending SwapBufferAck till that data is 158 // available. The callback should be run on the calling thread (i.e. same 159 // thread PostSubBufferAsync is called) 160 virtual void PostSubBufferAsync(int x, 161 int y, 162 int width, 163 int height, 164 SwapCompletionCallback completion_callback, 165 PresentationCallback presentation_callback); 166 167 // Show overlay planes but don't swap the front and back buffers. This acts 168 // like SwapBuffers from the point of view of the client, but is cheaper when 169 // overlays account for all the damage. If it returns SWAP_FAILED, 170 // it is possible that the context is no longer current. 171 virtual gfx::SwapResult CommitOverlayPlanes(PresentationCallback callback); 172 173 // Show overlay planes but don't swap the front and back buffers. On some 174 // platforms, we want to send SwapBufferAck only after the overlays are 175 // displayed on screen. The callback can be used to delay sending 176 // SwapBufferAck till that data is available. The callback should be run on 177 // the calling thread (i.e. same thread CommitOverlayPlanesAsync is called). 178 virtual void CommitOverlayPlanesAsync( 179 SwapCompletionCallback completion_callback, 180 PresentationCallback presentation_callback); 181 182 // Called after a context is made current with this surface. Returns false 183 // on error. 184 virtual bool OnMakeCurrent(GLContext* context); 185 186 // Used for explicit buffer management. 187 virtual bool SetBackbufferAllocation(bool allocated); 188 virtual void SetFrontbufferAllocation(bool allocated); 189 190 // Get a handle used to share the surface with another process. Returns null 191 // if this is not possible. 192 virtual void* GetShareHandle(); 193 194 // Get the platform specific display on which this surface resides, if 195 // available. 196 virtual void* GetDisplay(); 197 198 // Get the platfrom specific configuration for this surface, if available. 199 virtual void* GetConfig(); 200 201 // Get the GL pixel format of the surface. Must be implemented in a 202 // subclass, though it's ok to just "return GLSurfaceFormat()" if 203 // the default is appropriate. 204 virtual GLSurfaceFormat GetFormat() = 0; 205 206 // Get access to a helper providing time of recent refresh and period 207 // of screen refresh. If unavailable, returns NULL. 208 virtual gfx::VSyncProvider* GetVSyncProvider(); 209 210 // Set vsync to enabled or disabled. If supported, vsync is enabled by 211 // default. Does nothing if vsync cannot be changed. 212 virtual void SetVSyncEnabled(bool enabled); 213 214 // Schedule an overlay plane to be shown at swap time, or on the next 215 // CommitOverlayPlanes call. 216 // |z_order| specifies the stacking order of the plane relative to the 217 // main framebuffer located at index 0. For the case where there is no 218 // main framebuffer, overlays may be scheduled at 0, taking its place. 219 // |transform| specifies how the buffer is to be transformed during 220 // composition. 221 // |image| to be presented by the overlay. 222 // |bounds_rect| specify where it is supposed to be on the screen in pixels. 223 // |crop_rect| specifies the region within the buffer to be placed inside 224 // |bounds_rect|. 225 // |enable_blend| specifies if alpha blending, with premultiplied alpha 226 // should be applied at scanout. 227 virtual bool ScheduleOverlayPlane(int z_order, 228 gfx::OverlayTransform transform, 229 GLImage* image, 230 const gfx::Rect& bounds_rect, 231 const gfx::RectF& crop_rect, 232 bool enable_blend, 233 std::unique_ptr<gfx::GpuFence> gpu_fence); 234 235 // Schedule a CALayer to be shown at swap time. 236 // All arguments correspond to their CALayer properties. 237 virtual bool ScheduleCALayer(const ui::CARendererLayerParams& params); 238 239 struct GL_EXPORT CALayerInUseQuery { 240 CALayerInUseQuery(); 241 explicit CALayerInUseQuery(const CALayerInUseQuery&); 242 ~CALayerInUseQuery(); 243 unsigned texture = 0; 244 scoped_refptr<GLImage> image; 245 }; 246 virtual void ScheduleCALayerInUseQuery( 247 std::vector<CALayerInUseQuery> queries); 248 249 virtual bool ScheduleDCLayer(const ui::DCRendererLayerParams& params); 250 251 // Enables or disables DC layers, returning success. If failed, it is possible 252 // that the context is no longer current. 253 virtual bool SetEnableDCLayers(bool enable); 254 255 virtual bool IsSurfaceless() const; 256 257 virtual gfx::SurfaceOrigin GetOrigin() const; 258 259 // Returns true if SwapBuffers or PostSubBuffers causes a flip, such that 260 // the next buffer may be 2 frames old. 261 virtual bool BuffersFlipped() const; 262 263 virtual bool SupportsDCLayers() const; 264 265 virtual bool SupportsProtectedVideo() const; 266 267 // Set the rectangle that will be drawn into on the surface, returning 268 // success. If failed, it is possible that the context is no longer current. 269 virtual bool SetDrawRectangle(const gfx::Rect& rect); 270 271 // This is the amount by which the scissor and viewport rectangles should be 272 // offset. 273 virtual gfx::Vector2d GetDrawOffset() const; 274 275 // Tells the surface to rely on implicit sync when swapping buffers. 276 virtual void SetRelyOnImplicitSync(); 277 278 // Tells the surface to perform a glFlush() before swapping buffers. 279 virtual void SetForceGlFlushOnSwapBuffers(); 280 281 // Support for eglGetFrameTimestamps. 282 virtual bool SupportsSwapTimestamps() const; 283 virtual void SetEnableSwapTimestamps(); 284 285 virtual bool SupportsPlaneGpuFences() const; 286 287 // Returns the number of buffers the surface uses in the swap chain. For 288 // example, most surfaces are double-buffered, so this would return 2. For 289 // triple-buffered surfaces this would return 3, etc. 290 virtual int GetBufferCount() const; 291 292 // Return the interface used for querying EGL timestamps. 293 virtual EGLTimestampClient* GetEGLTimestampClient(); 294 295 virtual bool SupportsGpuVSync() const; 296 297 virtual void SetGpuVSyncEnabled(bool enabled); 298 SetDisplayTransform(gfx::OverlayTransform transform)299 virtual void SetDisplayTransform(gfx::OverlayTransform transform) {} 300 301 static GLSurface* GetCurrent(); 302 303 virtual void SetCurrent(); 304 virtual bool IsCurrent(); 305 306 static bool ExtensionsContain(const char* extensions, const char* name); 307 308 protected: 309 virtual ~GLSurface(); 310 311 private: 312 static void ClearCurrent(); 313 314 friend class base::RefCounted<GLSurface>; 315 friend class GLContext; 316 317 DISALLOW_COPY_AND_ASSIGN(GLSurface); 318 }; 319 320 // Implementation of GLSurface that forwards all calls through to another 321 // GLSurface. 322 class GL_EXPORT GLSurfaceAdapter : public GLSurface { 323 public: 324 explicit GLSurfaceAdapter(GLSurface* surface); 325 326 bool Initialize(GLSurfaceFormat format) override; 327 void PrepareToDestroy(bool have_context) override; 328 void Destroy() override; 329 bool Resize(const gfx::Size& size, 330 float scale_factor, 331 const gfx::ColorSpace& color_space, 332 bool has_alpha) override; 333 bool Recreate() override; 334 bool DeferDraws() override; 335 bool IsOffscreen() override; 336 gfx::SwapResult SwapBuffers(PresentationCallback callback) override; 337 void SwapBuffersAsync(SwapCompletionCallback completion_callback, 338 PresentationCallback presentation_callback) override; 339 gfx::SwapResult SwapBuffersWithBounds(const std::vector<gfx::Rect>& rects, 340 PresentationCallback callback) override; 341 gfx::SwapResult PostSubBuffer(int x, 342 int y, 343 int width, 344 int height, 345 PresentationCallback callback) override; 346 void PostSubBufferAsync(int x, 347 int y, 348 int width, 349 int height, 350 SwapCompletionCallback completion_callback, 351 PresentationCallback presentation_callback) override; 352 gfx::SwapResult CommitOverlayPlanes(PresentationCallback callback) override; 353 void CommitOverlayPlanesAsync( 354 SwapCompletionCallback completion_callback, 355 PresentationCallback presentation_callback) override; 356 bool SupportsSwapBuffersWithBounds() override; 357 bool SupportsPostSubBuffer() override; 358 bool SupportsCommitOverlayPlanes() override; 359 bool SupportsAsyncSwap() override; 360 gfx::Size GetSize() override; 361 void* GetHandle() override; 362 unsigned int GetBackingFramebufferObject() override; 363 bool OnMakeCurrent(GLContext* context) override; 364 bool SetBackbufferAllocation(bool allocated) override; 365 void SetFrontbufferAllocation(bool allocated) override; 366 void* GetShareHandle() override; 367 void* GetDisplay() override; 368 void* GetConfig() override; 369 GLSurfaceFormat GetFormat() override; 370 gfx::VSyncProvider* GetVSyncProvider() override; 371 void SetVSyncEnabled(bool enabled) override; 372 bool ScheduleOverlayPlane(int z_order, 373 gfx::OverlayTransform transform, 374 GLImage* image, 375 const gfx::Rect& bounds_rect, 376 const gfx::RectF& crop_rect, 377 bool enable_blend, 378 std::unique_ptr<gfx::GpuFence> gpu_fence) override; 379 bool ScheduleDCLayer(const ui::DCRendererLayerParams& params) override; 380 bool SetEnableDCLayers(bool enable) override; 381 bool IsSurfaceless() const override; 382 gfx::SurfaceOrigin GetOrigin() const override; 383 bool BuffersFlipped() const override; 384 bool SupportsDCLayers() const override; 385 bool SupportsProtectedVideo() const override; 386 bool SetDrawRectangle(const gfx::Rect& rect) override; 387 gfx::Vector2d GetDrawOffset() const override; 388 void SetRelyOnImplicitSync() override; 389 void SetForceGlFlushOnSwapBuffers() override; 390 bool SupportsSwapTimestamps() const override; 391 void SetEnableSwapTimestamps() override; 392 bool SupportsPlaneGpuFences() const override; 393 int GetBufferCount() const override; 394 bool SupportsGpuVSync() const override; 395 void SetGpuVSyncEnabled(bool enabled) override; 396 void SetDisplayTransform(gfx::OverlayTransform transform) override; 397 void SetCurrent() override; 398 bool IsCurrent() override; 399 surface()400 GLSurface* surface() const { return surface_.get(); } 401 402 protected: 403 ~GLSurfaceAdapter() override; 404 405 private: 406 scoped_refptr<GLSurface> surface_; 407 408 DISALLOW_COPY_AND_ASSIGN(GLSurfaceAdapter); 409 }; 410 411 // Wraps GLSurface in scoped_refptr and tries to initializes it. Returns a 412 // scoped_refptr containing the initialized GLSurface or nullptr if 413 // initialization fails. 414 GL_EXPORT scoped_refptr<GLSurface> InitializeGLSurface( 415 scoped_refptr<GLSurface> surface); 416 417 GL_EXPORT scoped_refptr<GLSurface> InitializeGLSurfaceWithFormat( 418 scoped_refptr<GLSurface> surface, GLSurfaceFormat format); 419 420 } // namespace gl 421 422 #endif // UI_GL_GL_SURFACE_H_ 423