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