1 // Copyright 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 COMPONENTS_VIZ_SERVICE_DISPLAY_OUTPUT_SURFACE_H_
6 #define COMPONENTS_VIZ_SERVICE_DISPLAY_OUTPUT_SURFACE_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "base/callback_helpers.h"
12 #include "base/containers/circular_deque.h"
13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/threading/thread_checker.h"
16 #include "components/viz/common/display/update_vsync_parameters_callback.h"
17 #include "components/viz/common/gpu/context_provider.h"
18 #include "components/viz/common/gpu/gpu_vsync_callback.h"
19 #include "components/viz/common/resources/resource_format.h"
20 #include "components/viz/common/resources/returned_resource.h"
21 #include "components/viz/service/display/software_output_device.h"
22 #include "components/viz/service/viz_service_export.h"
23 #include "gpu/command_buffer/common/mailbox.h"
24 #include "gpu/command_buffer/common/texture_in_use_response.h"
25 #include "gpu/ipc/common/surface_handle.h"
26 #include "gpu/ipc/gpu_task_scheduler_helper.h"
27 #include "third_party/skia/include/gpu/GrBackendSurface.h"
28 #include "ui/gfx/color_space.h"
29 #include "ui/gfx/overlay_transform.h"
30 #include "ui/gfx/surface_origin.h"
31 #include "ui/latency/latency_info.h"
32 
33 namespace gfx {
34 class ColorSpace;
35 class Rect;
36 class Size;
37 struct SwapResponse;
38 }  // namespace gfx
39 
40 namespace viz {
41 class OutputSurfaceClient;
42 class OutputSurfaceFrame;
43 class SkiaOutputSurface;
44 
45 // This class represents a platform-independent API for presenting
46 // buffers to display via GPU or software compositing. Implementations
47 // can provide platform-specific behaviour.
48 class VIZ_SERVICE_EXPORT OutputSurface {
49  public:
50   enum Type {
51     kSoftware = 0,
52     kOpenGL = 1,
53     kVulkan = 2,
54   };
55   struct Capabilities {
56     Capabilities();
57     Capabilities(const Capabilities& capabilities);
58 
59     int max_frames_pending = 1;
60     // Whether this output surface renders to the default OpenGL zero
61     // framebuffer or to an offscreen framebuffer.
62     bool uses_default_gl_framebuffer = true;
63     // Where (0,0) is on this OutputSurface.
64     gfx::SurfaceOrigin output_surface_origin = gfx::SurfaceOrigin::kBottomLeft;
65     // Whether this OutputSurface supports stencil operations or not.
66     // Note: HasExternalStencilTest() must return false when an output surface
67     // has been configured for stencil usage.
68     bool supports_stencil = false;
69     // Whether this OutputSurface supports post sub buffer or not.
70     bool supports_post_sub_buffer = false;
71     // Whether this OutputSurface supports commit overlay planes.
72     bool supports_commit_overlay_planes = false;
73     // Whether this OutputSurface supports gpu vsync callbacks.
74     bool supports_gpu_vsync = false;
75     // Whether this OutputSurface supports pre transform. If it is supported,
76     // the chrome will set the output surface size in hardware natural
77     // orientation, and will render transformed content on back buffers based
78     // on the current system transform. So the OS presentation engine can
79     // present buffers onto the screen directly.
80     bool supports_pre_transform = false;
81     // Whether this OutputSurface supports direct composition layers.
82     bool supports_dc_layers = false;
83     // Whether this OutputSurface should skip DrawAndSwap(). This is true for
84     // the unified display on Chrome OS. All drawing is handled by the physical
85     // displays so the unified display should skip that work.
86     bool skips_draw = false;
87     // Indicates whether this surface will invalidate only the damage rect.
88     // When this is false contents outside the damaged area might need to be
89     // recomposited to the surface.
90     bool only_invalidates_damage_rect = true;
91     // Whether the gpu supports surfaceless surface (equivalent of using buffer
92     // queue).
93     bool supports_surfaceless = false;
94     // This is copied over from gpu feature info since there is no easy way to
95     // share that out of skia output surface.
96     bool android_surface_control_feature_enabled = false;
97     // True if the buffer content will be preserved after presenting.
98     bool preserve_buffer_content = false;
99     // The SkColorType and GrBackendFormat for non-HDR and HDR.
100     // TODO(penghuang): remove SkColorType and GrBackendFormat when
101     // OutputSurface uses the |format| passed to Reshape().
102     SkColorType sk_color_type = kUnknown_SkColorType;
103     GrBackendFormat gr_backend_format;
104     SkColorType sk_color_type_for_hdr = kUnknown_SkColorType;
105     GrBackendFormat gr_backend_format_for_hdr;
106   };
107 
108   // Constructor for skia-based compositing.
109   explicit OutputSurface(Type type);
110   // Constructor for GL-based compositing.
111   explicit OutputSurface(scoped_refptr<ContextProvider> context_provider);
112   // Constructor for software compositing.
113   explicit OutputSurface(std::unique_ptr<SoftwareOutputDevice> software_device);
114 
115   virtual ~OutputSurface();
116 
capabilities()117   const Capabilities& capabilities() const { return capabilities_; }
type()118   Type type() const { return type_; }
119 
120   // Obtain the 3d context or the software device associated with this output
121   // surface. Either of these may return a null pointer, but not both.
122   // In the event of a lost context, the entire output surface should be
123   // recreated.
context_provider()124   ContextProvider* context_provider() const { return context_provider_.get(); }
software_device()125   SoftwareOutputDevice* software_device() const {
126     return software_device_.get();
127   }
128 
129   // Downcasts to SkiaOutputSurface if it is one and returns nullptr otherwise.
130   virtual SkiaOutputSurface* AsSkiaOutputSurface();
131 
set_color_matrix(const SkMatrix44 & color_matrix)132   void set_color_matrix(const SkMatrix44& color_matrix) {
133     color_matrix_ = color_matrix;
134   }
color_matrix()135   const SkMatrix44& color_matrix() const { return color_matrix_; }
136 
137   // Only useful for GPU backend.
138   virtual gpu::SurfaceHandle GetSurfaceHandle() const;
139 
140   virtual void BindToClient(OutputSurfaceClient* client) = 0;
141 
142   virtual void EnsureBackbuffer() = 0;
143   virtual void DiscardBackbuffer() = 0;
144 
145   // Bind the default framebuffer for drawing to, only valid for GL backed
146   // OutputSurfaces.
147   virtual void BindFramebuffer() = 0;
148 
149   // Marks that the given rectangle will be drawn to on the default, bound
150   // framebuffer.
151   virtual void SetDrawRectangle(const gfx::Rect& rect) = 0;
152 
153   // Returns true if a main image overlay plane should be scheduled.
154   virtual bool IsDisplayedAsOverlayPlane() const = 0;
155 
156   // Get the texture for the main image's overlay.
157   virtual unsigned GetOverlayTextureId() const = 0;
158 
159   // Returns the |mailbox| corresponding to the main image's overlay.
160   virtual gpu::Mailbox GetOverlayMailbox() const;
161 
162   virtual void Reshape(const gfx::Size& size,
163                        float device_scale_factor,
164                        const gfx::ColorSpace& color_space,
165                        gfx::BufferFormat format,
166                        bool use_stencil) = 0;
167 
168   virtual bool HasExternalStencilTest() const = 0;
169   virtual void ApplyExternalStencil() = 0;
170 
171   // Gives the GL internal format that should be used for calling CopyTexImage2D
172   // when the framebuffer is bound via BindFramebuffer().
173   virtual uint32_t GetFramebufferCopyTextureFormat() = 0;
174 
175   // Swaps the current backbuffer to the screen. For successful swaps, the
176   // implementation must call OutputSurfaceClient::DidReceiveSwapBuffersAck()
177   // after returning from this method in order to unblock the next frame.
178   virtual void SwapBuffers(OutputSurfaceFrame frame) = 0;
179 
180   // Returns a rectangle whose contents may have changed since the current
181   // buffer was last submitted and needs to be redrawn. For partial swap,
182   // the contents outside this rectangle can be considered valid and do not need
183   // to be redrawn.
184   // In cases where partial swap is disabled, this method will still be called.
185   // The direct renderer will union the returned rect with the rectangle of the
186   // surface itself.
187   // TODO(dcastagna): Consider making the following pure virtual.
188   virtual gfx::Rect GetCurrentFramebufferDamage() const;
189 
190   // Updates the GpuFence associated with this surface. The id of a newly
191   // created GpuFence is returned, or if an error occurs, or fences are not
192   // supported, the special id of 0 (meaning "no fence") is returned.  In all
193   // cases, any previously associated fence is destroyed. The returned fence id
194   // corresponds to the GL id used by the CHROMIUM_gpu_fence GL extension and
195   // can be passed directly to any related extension functions.
196   virtual unsigned UpdateGpuFence() = 0;
197 
198   // Sets callback to receive updated vsync parameters after SwapBuffers() if
199   // supported.
200   virtual void SetUpdateVSyncParametersCallback(
201       UpdateVSyncParametersCallback callback) = 0;
202 
203   // Set a callback for vsync signal from GPU service for begin frames.  The
204   // callbacks must be received on the calling thread.
205   virtual void SetGpuVSyncCallback(GpuVSyncCallback callback);
206 
207   // Enable or disable vsync callback based on whether begin frames are needed.
208   virtual void SetGpuVSyncEnabled(bool enabled);
209 
210   // When the device is rotated, the scene prepared by the UI is in the logical
211   // screen space as seen by the user. However, attempting to scanout a buffer
212   // with its content in this logical space may be unsupported or inefficient
213   // when rendered by the display hardware.
214   //
215   // In order to avoid this, this API provides the OutputSurface with the
216   // transform/rotation that should be applied to the display compositor's
217   // output. This is the same rotation as the physical rotation on the display.
218   // In some cases, this is done natively by the graphics backend (
219   // For instance, this is already done by GL drivers on Android. See
220   // https://source.android.com/devices/graphics/implement#pre-rotation).
221   //
222   // If not supported natively, the OutputSurface should return the transform
223   // needed in GetDisplayTransform for it to explicitly applied by the
224   // compositor.
225   virtual void SetDisplayTransformHint(gfx::OverlayTransform transform) = 0;
226   virtual gfx::OverlayTransform GetDisplayTransform() = 0;
227 
228   virtual base::ScopedClosureRunner GetCacheBackBufferCb();
229 
230   // If set to true, the OutputSurface must deliver
231   // OutputSurfaceclient::DidSwapWithSize notifications to its client.
232   // OutputSurfaces which support delivering swap size notifications should
233   // override this.
234   virtual void SetNeedsSwapSizeNotifications(
235       bool needs_swap_size_notifications);
236 
237   // Updates timing info on the provided LatencyInfo when swap completes.
238   static void UpdateLatencyInfoOnSwap(
239       const gfx::SwapResponse& response,
240       std::vector<ui::LatencyInfo>* latency_info);
241 
242   // This is used to share the same method to schedule task on the gpu thread
243   // between the output surface and the overlay processor.
244   // TODO(weiliangc): Consider making this outside of output surface and pass in
245   // instead of passing it out here.
246   virtual scoped_refptr<gpu::GpuTaskSchedulerHelper>
247   GetGpuTaskSchedulerHelper() = 0;
248   virtual gpu::MemoryTracker* GetMemoryTracker() = 0;
249 
250  protected:
251   struct OutputSurface::Capabilities capabilities_;
252   scoped_refptr<ContextProvider> context_provider_;
253   std::unique_ptr<SoftwareOutputDevice> software_device_;
254 
255  private:
256   const Type type_;
257   SkMatrix44 color_matrix_;
258 
259   DISALLOW_COPY_AND_ASSIGN(OutputSurface);
260 };
261 
262 }  // namespace viz
263 
264 #endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_OUTPUT_SURFACE_H_
265