1 // Copyright 2014 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_DISPLAY_H_ 6 #define COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_H_ 7 8 #include <memory> 9 #include <vector> 10 11 #include "base/containers/circular_deque.h" 12 #include "base/macros.h" 13 #include "base/memory/weak_ptr.h" 14 #include "base/observer_list.h" 15 #include "base/single_thread_task_runner.h" 16 #include "base/time/time.h" 17 #include "components/viz/common/frame_sinks/begin_frame_source.h" 18 #include "components/viz/common/gpu/context_lost_observer.h" 19 #include "components/viz/common/resources/returned_resource.h" 20 #include "components/viz/common/surfaces/frame_sink_id.h" 21 #include "components/viz/common/surfaces/surface_id.h" 22 #include "components/viz/service/display/display_resource_provider.h" 23 #include "components/viz/service/display/display_scheduler.h" 24 #include "components/viz/service/display/frame_rate_decider.h" 25 #include "components/viz/service/display/output_surface_client.h" 26 #include "components/viz/service/display/overlay_processor_interface.h" 27 #include "components/viz/service/display/software_output_device_client.h" 28 #include "components/viz/service/display/surface_aggregator.h" 29 #include "components/viz/service/surfaces/latest_local_surface_id_lookup_delegate.h" 30 #include "components/viz/service/surfaces/surface.h" 31 #include "components/viz/service/surfaces/surface_manager.h" 32 #include "components/viz/service/viz_service_export.h" 33 #include "gpu/command_buffer/common/texture_in_use_response.h" 34 #include "ui/gfx/display_color_spaces.h" 35 #include "ui/gfx/overlay_transform.h" 36 #include "ui/gfx/swap_result.h" 37 #include "ui/latency/latency_info.h" 38 39 namespace gfx { 40 class Size; 41 } 42 43 namespace gpu { 44 class ScopedAllowScheduleGpuTask; 45 } 46 47 namespace viz { 48 class DirectRenderer; 49 class DisplayClient; 50 class DisplayResourceProvider; 51 class OutputSurface; 52 class RendererSettings; 53 class SharedBitmapManager; 54 class SkiaOutputSurface; 55 class SoftwareRenderer; 56 57 class VIZ_SERVICE_EXPORT DisplayObserver { 58 public: ~DisplayObserver()59 virtual ~DisplayObserver() {} 60 61 virtual void OnDisplayDidFinishFrame(const BeginFrameAck& ack) = 0; 62 virtual void OnDisplayDestroyed() = 0; 63 }; 64 65 // A Display produces a surface that can be used to draw to a physical display 66 // (OutputSurface). The client is responsible for creating and sizing the 67 // surface IDs used to draw into the display and deciding when to draw. 68 class VIZ_SERVICE_EXPORT Display : public DisplaySchedulerClient, 69 public OutputSurfaceClient, 70 public ContextLostObserver, 71 public LatestLocalSurfaceIdLookupDelegate, 72 public SoftwareOutputDeviceClient, 73 public FrameRateDecider::Client { 74 public: 75 // The |begin_frame_source| and |scheduler| may be null (together). In that 76 // case, DrawAndSwap must be called externally when needed. 77 // The |current_task_runner| may be null if the Display is on a thread without 78 // a MessageLoop. 79 // TODO(penghuang): Remove skia_output_surface when all DirectRenderer 80 // subclasses are replaced by SkiaRenderer. 81 Display(SharedBitmapManager* bitmap_manager, 82 const RendererSettings& settings, 83 const FrameSinkId& frame_sink_id, 84 std::unique_ptr<OutputSurface> output_surface, 85 std::unique_ptr<OverlayProcessorInterface> overlay_processor, 86 std::unique_ptr<DisplaySchedulerBase> scheduler, 87 scoped_refptr<base::SingleThreadTaskRunner> current_task_runner); 88 89 ~Display() override; 90 91 static constexpr base::TimeDelta kDrawToSwapMin = 92 base::TimeDelta::FromMicroseconds(5); 93 static constexpr base::TimeDelta kDrawToSwapMax = 94 base::TimeDelta::FromMilliseconds(50); 95 static constexpr uint32_t kDrawToSwapUsBuckets = 50; 96 97 // TODO(cblume, crbug.com/900973): |enable_shared_images| is a temporary 98 // solution that unblocks us until SharedImages are threadsafe in WebView. 99 #if defined(ANDROID) 100 static constexpr bool kEnableSharedImages = false; 101 #else 102 static constexpr bool kEnableSharedImages = true; 103 #endif 104 void Initialize(DisplayClient* client, 105 SurfaceManager* surface_manager, 106 bool enable_shared_images = kEnableSharedImages, 107 bool using_synthetic_bfs = false); 108 109 void AddObserver(DisplayObserver* observer); 110 void RemoveObserver(DisplayObserver* observer); 111 112 // device_scale_factor is used to communicate to the external window system 113 // what scale this was rendered at. 114 void SetLocalSurfaceId(const LocalSurfaceId& id, float device_scale_factor); 115 void SetVisible(bool visible); 116 void Resize(const gfx::Size& new_size); 117 118 // Stop drawing until Resize() is called with a new size. If the display 119 // hasn't drawn a frame at the current size *and* it's possible to immediately 120 // draw then this will run DrawAndSwap() first. 121 // 122 // |no_pending_swaps_callback| will be run there are no more swaps pending and 123 // may be run immediately. 124 void DisableSwapUntilResize(base::OnceClosure no_pending_swaps_callback); 125 126 // Sets the color matrix that will be used to transform the output of this 127 // display. This is only supported for GPU compositing. 128 void SetColorMatrix(const SkMatrix44& matrix); 129 130 void SetDisplayColorSpaces( 131 const gfx::DisplayColorSpaces& display_color_spaces); 132 void SetOutputIsSecure(bool secure); 133 134 const SurfaceId& CurrentSurfaceId(); 135 136 // DisplaySchedulerClient implementation. 137 bool DrawAndSwap(base::TimeTicks expected_display_time) override; 138 void DidFinishFrame(const BeginFrameAck& ack) override; 139 140 // OutputSurfaceClient implementation. 141 void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override; 142 void DidReceiveSwapBuffersAck(const gfx::SwapTimings& timings) override; 143 void DidReceiveTextureInUseResponses( 144 const gpu::TextureInUseResponses& responses) override; 145 void DidReceiveCALayerParams( 146 const gfx::CALayerParams& ca_layer_params) override; 147 void DidSwapWithSize(const gfx::Size& pixel_size) override; 148 void DidReceivePresentationFeedback( 149 const gfx::PresentationFeedback& feedback) override; 150 151 // LatestLocalSurfaceIdLookupDelegate implementation. 152 LocalSurfaceId GetSurfaceAtAggregation( 153 const FrameSinkId& frame_sink_id) const override; 154 155 // SoftwareOutputDeviceClient implementation 156 void SoftwareDeviceUpdatedCALayerParams( 157 const gfx::CALayerParams& ca_layer_params) override; 158 159 // FrameRateDecider::Client implementation 160 void SetPreferredFrameInterval(base::TimeDelta interval) override; 161 base::TimeDelta GetPreferredFrameIntervalForFrameSinkId( 162 const FrameSinkId& id) override; 163 has_scheduler()164 bool has_scheduler() const { return !!scheduler_; } renderer_for_testing()165 DirectRenderer* renderer_for_testing() const { return renderer_.get(); } 166 167 void ForceImmediateDrawAndSwapIfPossible(); 168 void SetNeedsOneBeginFrame(); 169 void RemoveOverdrawQuads(CompositorFrame* frame); 170 171 void SetSupportedFrameIntervals(std::vector<base::TimeDelta> intervals); 172 173 base::ScopedClosureRunner GetCacheBackBufferCb(); 174 175 #if defined(TOOLKIT_QT) frame_sink_id()176 FrameSinkId frame_sink_id() const { return frame_sink_id_; } 177 #endif 178 179 bool IsRootFrameMissing() const; 180 bool HasPendingSurfaces(const BeginFrameArgs& args) const; 181 182 private: 183 friend class DisplayTest; 184 // PresentationGroupTiming stores rendering pipeline stage timings associated 185 // with a call to Display::DrawAndSwap along with a list of 186 // Surface::PresentationHelper's for each aggregated Surface that will be 187 // presented. 188 class PresentationGroupTiming { 189 public: 190 PresentationGroupTiming(); 191 PresentationGroupTiming(PresentationGroupTiming&& other); 192 ~PresentationGroupTiming(); 193 194 void AddPresentationHelper( 195 std::unique_ptr<Surface::PresentationHelper> helper); 196 void OnDraw(base::TimeTicks draw_start_timestamp); 197 void OnSwap(gfx::SwapTimings timings); HasSwapped()198 bool HasSwapped() const { return !swap_timings_.is_null(); } 199 void OnPresent(const gfx::PresentationFeedback& feedback); 200 draw_start_timestamp()201 base::TimeTicks draw_start_timestamp() const { 202 return draw_start_timestamp_; 203 } 204 205 private: 206 base::TimeTicks draw_start_timestamp_; 207 gfx::SwapTimings swap_timings_; 208 std::vector<std::unique_ptr<Surface::PresentationHelper>> 209 presentation_helpers_; 210 211 DISALLOW_COPY_AND_ASSIGN(PresentationGroupTiming); 212 }; 213 214 // TODO(cblume, crbug.com/900973): |enable_shared_images| is a temporary 215 // solution that unblocks us until SharedImages are threadsafe in WebView. 216 void InitializeRenderer(bool enable_shared_images = true); 217 218 // ContextLostObserver implementation. 219 void OnContextLost() override; 220 221 SharedBitmapManager* const bitmap_manager_; 222 const RendererSettings settings_; 223 224 DisplayClient* client_ = nullptr; 225 base::ObserverList<DisplayObserver>::Unchecked observers_; 226 SurfaceManager* surface_manager_ = nullptr; 227 const FrameSinkId frame_sink_id_; 228 SurfaceId current_surface_id_; 229 gfx::Size current_surface_size_; 230 float device_scale_factor_ = 1.f; 231 gfx::DisplayColorSpaces display_color_spaces_; 232 bool visible_ = false; 233 bool swapped_since_resize_ = false; 234 bool output_is_secure_ = false; 235 236 #if DCHECK_IS_ON() 237 std::unique_ptr<gpu::ScopedAllowScheduleGpuTask> 238 allow_schedule_gpu_task_during_destruction_; 239 #endif 240 std::unique_ptr<OutputSurface> output_surface_; 241 SkiaOutputSurface* const skia_output_surface_; 242 std::unique_ptr<DisplayDamageTracker> damage_tracker_; 243 std::unique_ptr<DisplaySchedulerBase> scheduler_; 244 std::unique_ptr<DisplayResourceProvider> resource_provider_; 245 std::unique_ptr<SurfaceAggregator> aggregator_; 246 std::unique_ptr<FrameRateDecider> frame_rate_decider_; 247 // This may be null if the Display is on a thread without a MessageLoop. 248 scoped_refptr<base::SingleThreadTaskRunner> current_task_runner_; 249 std::unique_ptr<DirectRenderer> renderer_; 250 SoftwareRenderer* software_renderer_ = nullptr; 251 // Currently, this OverlayProcessor takes raw pointer to memory tracker, which 252 // is owned by the OutputSurface. This OverlayProcessor also takes resource 253 // locks which contains raw pointers to DisplayResourceProvider. Make sure 254 // both the OutputSurface and the DisplayResourceProvider outlive the 255 // Overlay Processor. 256 std::unique_ptr<OverlayProcessorInterface> overlay_processor_; 257 std::vector<ui::LatencyInfo> stored_latency_info_; 258 std::vector<gfx::Rect> cached_visible_region_; 259 260 // |pending_presentation_group_timings_| stores a 261 // Display::PresentationGroupTiming for each group currently waiting for 262 // Display::DidReceivePresentationFeedack() 263 base::circular_deque<Display::PresentationGroupTiming> 264 pending_presentation_group_timings_; 265 266 bool disable_swap_until_resize_ = true; 267 268 bool enable_quad_splitting_ = true; 269 270 // Callback that will be run after all pending swaps have acked. 271 base::OnceClosure no_pending_swaps_callback_; 272 273 int64_t swapped_trace_id_ = 0; 274 int64_t last_swap_ack_trace_id_ = 0; 275 int64_t last_presented_trace_id_ = 0; 276 int pending_swaps_ = 0; 277 278 // The height of the top-controls in the previously drawn frame. 279 float last_top_controls_visible_height_ = 0.f; 280 281 DISALLOW_COPY_AND_ASSIGN(Display); 282 }; 283 284 } // namespace viz 285 286 #endif // COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_H_ 287