1 // Copyright 2016 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_OZONE_PLATFORM_DRM_GPU_GBM_SURFACELESS_H_
6 #define UI_OZONE_PLATFORM_DRM_GPU_GBM_SURFACELESS_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "base/macros.h"
12 #include "base/memory/weak_ptr.h"
13 #include "ui/gfx/native_widget_types.h"
14 #include "ui/gl/gl_image.h"
15 #include "ui/gl/gl_surface_egl.h"
16 #include "ui/gl/gl_surface_overlay.h"
17 #include "ui/gl/scoped_binders.h"
18 #include "ui/ozone/platform/drm/gpu/drm_overlay_plane.h"
19 
20 namespace gfx {
21 class GpuFence;
22 }  // namespace gfx
23 
24 namespace ui {
25 
26 class DrmWindowProxy;
27 class GbmSurfaceFactory;
28 
29 // A GLSurface for GBM Ozone platform that uses surfaceless drawing. Drawing and
30 // displaying happens directly through NativePixmap buffers. CC would call into
31 // SurfaceFactoryOzone to allocate the buffers and then call
32 // ScheduleOverlayPlane(..) to schedule the buffer for presentation.
33 class GbmSurfaceless : public gl::SurfacelessEGL {
34  public:
35   GbmSurfaceless(GbmSurfaceFactory* surface_factory,
36                  std::unique_ptr<DrmWindowProxy> window,
37                  gfx::AcceleratedWidget widget);
38 
39   void QueueOverlayPlane(DrmOverlayPlane plane);
40 
41   // gl::GLSurface:
42   bool Initialize(gl::GLSurfaceFormat format) override;
43   gfx::SwapResult SwapBuffers(PresentationCallback callback) override;
44   bool ScheduleOverlayPlane(int z_order,
45                             gfx::OverlayTransform transform,
46                             gl::GLImage* image,
47                             const gfx::Rect& bounds_rect,
48                             const gfx::RectF& crop_rect,
49                             bool enable_blend,
50                             std::unique_ptr<gfx::GpuFence> gpu_fence) override;
51   bool Resize(const gfx::Size& size,
52               float scale_factor,
53               const gfx::ColorSpace& color_space,
54               bool has_alpha) override;
55   bool IsOffscreen() override;
56   bool SupportsAsyncSwap() override;
57   bool SupportsPostSubBuffer() override;
58   bool SupportsPlaneGpuFences() const override;
59   gfx::SwapResult PostSubBuffer(int x,
60                                 int y,
61                                 int width,
62                                 int height,
63                                 PresentationCallback callback) override;
64   void SwapBuffersAsync(SwapCompletionCallback completion_callback,
65                         PresentationCallback presentation_callback) override;
66   void PostSubBufferAsync(int x,
67                           int y,
68                           int width,
69                           int height,
70                           SwapCompletionCallback completion_callback,
71                           PresentationCallback presentation_callback) override;
72   EGLConfig GetConfig() override;
73   void SetRelyOnImplicitSync() override;
74   void SetForceGlFlushOnSwapBuffers() override;
75   gfx::SurfaceOrigin GetOrigin() const override;
76 
77  protected:
78   ~GbmSurfaceless() override;
79 
widget()80   gfx::AcceleratedWidget widget() { return widget_; }
surface_factory()81   GbmSurfaceFactory* surface_factory() { return surface_factory_; }
82 
83  private:
84   struct PendingFrame {
85     PendingFrame();
86     ~PendingFrame();
87 
88     bool ScheduleOverlayPlanes(gfx::AcceleratedWidget widget);
89     void Flush();
90 
91     bool ready = false;
92     gfx::SwapResult swap_result = gfx::SwapResult::SWAP_FAILED;
93     std::vector<gl::GLSurfaceOverlay> overlays;
94     SwapCompletionCallback completion_callback;
95     PresentationCallback presentation_callback;
96   };
97 
98   void SubmitFrame();
99 
100   EGLSyncKHR InsertFence(bool implicit);
101   void FenceRetired(PendingFrame* frame);
102 
103   void OnSubmission(gfx::SwapResult result,
104                     std::unique_ptr<gfx::GpuFence> out_fence);
105   void OnPresentation(const gfx::PresentationFeedback& feedback);
106 
107   GbmSurfaceFactory* const surface_factory_;
108   const std::unique_ptr<DrmWindowProxy> window_;
109   std::vector<DrmOverlayPlane> planes_;
110 
111   // The native surface. Deleting this is allowed to free the EGLNativeWindow.
112   const gfx::AcceleratedWidget widget_;
113   std::unique_ptr<gfx::VSyncProvider> vsync_provider_;
114   std::vector<std::unique_ptr<PendingFrame>> unsubmitted_frames_;
115   std::unique_ptr<PendingFrame> submitted_frame_;
116   std::unique_ptr<gfx::GpuFence> submitted_frame_gpu_fence_;
117   const bool has_implicit_external_sync_;
118   const bool has_image_flush_external_;
119   bool last_swap_buffers_result_ = true;
120   bool supports_plane_gpu_fences_ = false;
121   bool use_egl_fence_sync_ = true;
122 
123   // Conservatively assume we begin on a device that requires
124   // explicit synchronization.
125   bool is_on_external_drm_device_ = true;
126   bool requires_gl_flush_on_swap_buffers_ = false;
127 
128   base::WeakPtrFactory<GbmSurfaceless> weak_factory_{this};
129 
130   DISALLOW_COPY_AND_ASSIGN(GbmSurfaceless);
131 };
132 
133 }  // namespace ui
134 
135 #endif  // UI_OZONE_PLATFORM_DRM_GPU_GBM_SURFACELESS_H_
136