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.
5 #ifndef UI_ACCELERATED_WIDGET_MAC_ACCELERATED_WIDGET_MAC_H_
6 #define UI_ACCELERATED_WIDGET_MAC_ACCELERATED_WIDGET_MAC_H_
8 #include <IOSurface/IOSurfaceAPI.h>
11 #include "ui/accelerated_widget_mac/accelerated_widget_mac_export.h"
12 #include "ui/events/latency_info.h"
13 #include "ui/gfx/geometry/rect.h"
14 #include "ui/gfx/geometry/size.h"
15 #include "ui/gfx/native_widget_types.h"
18 #import <Cocoa/Cocoa.h>
19 #import "base/mac/scoped_nsobject.h"
20 #import "ui/accelerated_widget_mac/io_surface_layer.h"
21 #import "ui/accelerated_widget_mac/software_layer.h"
22 #include "ui/base/cocoa/remote_layer_api.h"
28 class SoftwareFrameData
;
33 class AcceleratedWidgetMac
;
35 // A class through which an AcceleratedWidget may be bound to draw the contents
36 // of an NSView. An AcceleratedWidget may be bound to multiple different views
37 // throughout its lifetime (one at a time, though).
38 class AcceleratedWidgetMacNSView
{
40 virtual NSView
* AcceleratedWidgetGetNSView() const = 0;
41 virtual bool AcceleratedWidgetShouldIgnoreBackpressure() const = 0;
42 virtual void AcceleratedWidgetSwapCompleted(
43 const std::vector
<ui::LatencyInfo
>& latency_info
) = 0;
44 virtual void AcceleratedWidgetHitError() = 0;
49 // AcceleratedWidgetMac owns a tree of CALayers. The widget may be passed
50 // to a ui::Compositor, which will cause, through its output surface, calls to
51 // GotAcceleratedFrame and GotSoftwareFrame. The CALayers may be installed
52 // in an NSView by setting the AcceleratedWidgetMacNSView for the helper.
53 class ACCELERATED_WIDGET_MAC_EXPORT AcceleratedWidgetMac
54 : public IOSurfaceLayerClient
{
56 explicit AcceleratedWidgetMac(bool needs_gl_finish_workaround
);
57 virtual ~AcceleratedWidgetMac();
59 gfx::AcceleratedWidget
accelerated_widget() { return native_widget_
; }
61 void SetNSView(AcceleratedWidgetMacNSView
* view
);
64 // Return true if the last frame swapped has a size in DIP of |dip_size|.
65 bool HasFrameOfSize(const gfx::Size
& dip_size
) const;
67 // Return the CGL renderer ID for the surface, if one is available.
68 int GetRendererID() const;
70 // Return true if the renderer should not be throttled by GPU back-pressure.
71 bool IsRendererThrottlingDisabled() const;
73 // Mark a bracket in which new frames are being pumped in a restricted nested
75 void BeginPumpingFrames();
76 void EndPumpingFrames();
78 void GotAcceleratedFrame(
79 uint64 surface_handle
,
80 const std::vector
<ui::LatencyInfo
>& latency_info
,
81 const gfx::Size
& pixel_size
,
83 const gfx::Rect
& pixel_damage_rect
,
84 const base::Closure
& drawn_callback
);
86 void GotSoftwareFrame(float scale_factor
, SkCanvas
* canvas
);
89 // IOSurfaceLayerClient implementation:
90 bool IOSurfaceLayerShouldAckImmediately() const override
;
91 void IOSurfaceLayerDidDrawFrame() override
;
92 void IOSurfaceLayerHitError() override
;
94 void GotAcceleratedCAContextFrame(CAContextID ca_context_id
,
95 const gfx::Size
& pixel_size
,
98 void GotAcceleratedIOSurfaceFrame(IOSurfaceID io_surface_id
,
99 const gfx::Size
& pixel_size
,
102 void AcknowledgeAcceleratedFrame();
104 // Remove a layer from the heirarchy and destroy it. Because the accelerated
105 // layer types may be replaced by a layer of the same type, the layer to
106 // destroy is parameterized, and, if it is the current layer, the current
108 void DestroyCAContextLayer(
109 base::scoped_nsobject
<CALayerHost
> ca_context_layer
);
110 void DestroyIOSurfaceLayer(
111 base::scoped_nsobject
<IOSurfaceLayer
> io_surface_layer
);
112 void DestroySoftwareLayer();
114 // The AcceleratedWidgetMacNSView that is using this as its internals.
115 AcceleratedWidgetMacNSView
* view_
;
117 // A phony NSView handle used to identify this.
118 gfx::AcceleratedWidget native_widget_
;
120 // A flipped layer, which acts as the parent of the compositing and software
121 // layers. This layer is flipped so that the we don't need to recompute the
122 // origin for sub-layers when their position changes (this is impossible when
123 // using remote layers, as their size change cannot be synchronized with the
124 // window). This indirection is needed because flipping hosted layers (like
125 // |background_layer_| of RenderWidgetHostViewCocoa) leads to unpredictable
127 base::scoped_nsobject
<CALayer
> flipped_layer_
;
129 // The accelerated CoreAnimation layer hosted by the GPU process.
130 base::scoped_nsobject
<CALayerHost
> ca_context_layer_
;
132 // The locally drawn accelerated CoreAnimation layer.
133 base::scoped_nsobject
<IOSurfaceLayer
> io_surface_layer_
;
135 // The locally drawn software layer.
136 base::scoped_nsobject
<SoftwareLayer
> software_layer_
;
138 // If an accelerated frame has come in which has not yet been drawn and acked
139 // then this is the latency info and the callback to make when the frame is
140 // drawn. If there is no such frame then the callback is null.
141 std::vector
<ui::LatencyInfo
> accelerated_latency_info_
;
142 base::Closure accelerated_frame_drawn_callback_
;
144 // The size in DIP of the last swap received from |compositor_|.
145 gfx::Size last_swap_size_dip_
;
147 // Whether surfaces created by the widget should use the glFinish() workaround
148 // after compositing.
149 bool needs_gl_finish_workaround_
;
151 DISALLOW_COPY_AND_ASSIGN(AcceleratedWidgetMac
);
156 ACCELERATED_WIDGET_MAC_EXPORT
157 void AcceleratedWidgetMacGotAcceleratedFrame(
158 gfx::AcceleratedWidget widget
, uint64 surface_handle
,
159 const std::vector
<ui::LatencyInfo
>& latency_info
,
160 const gfx::Size
& pixel_size
,
162 const gfx::Rect
& pixel_damage_rect
,
163 const base::Closure
& drawn_callback
,
164 bool* disable_throttling
, int* renderer_id
);
166 ACCELERATED_WIDGET_MAC_EXPORT
167 void AcceleratedWidgetMacGotSoftwareFrame(
168 gfx::AcceleratedWidget widget
, float scale_factor
, SkCanvas
* canvas
);
172 #endif // UI_ACCELERATED_WIDGET_MAC_ACCELERATED_WIDGET_MAC_H_