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 CONTENT_BROWSER_COMPOSITOR_BROWSER_COMPOSITOR_VIEW_PRIVATE_MAC_H_
6#define CONTENT_BROWSER_COMPOSITOR_BROWSER_COMPOSITOR_VIEW_PRIVATE_MAC_H_
7
8#include <IOSurface/IOSurfaceAPI.h>
9
10#include "base/mac/scoped_nsobject.h"
11#include "content/browser/compositor/browser_compositor_view_mac.h"
12#include "content/browser/compositor/io_surface_layer_mac.h"
13#include "content/browser/compositor/software_layer_mac.h"
14#include "ui/base/cocoa/remote_layer_api.h"
15
16namespace content {
17
18// BrowserCompositorViewMacInternal owns a NSView and a ui::Compositor that
19// draws that view.
20class BrowserCompositorViewMacInternal
21    : public IOSurfaceLayerClient {
22 public:
23  BrowserCompositorViewMacInternal();
24  virtual ~BrowserCompositorViewMacInternal();
25  static BrowserCompositorViewMacInternal* FromAcceleratedWidget(
26      gfx::AcceleratedWidget widget);
27
28  void SetClient(BrowserCompositorViewMacClient* client);
29  void ResetClient();
30
31  ui::Compositor* compositor() const { return compositor_.get(); }
32
33  // Return true if the last frame swapped has a size in DIP of |dip_size|.
34  bool HasFrameOfSize(const gfx::Size& dip_size) const;
35
36  // Return the CGL renderer ID for the surface, if one is available.
37  int GetRendererID() const;
38
39  // Mark a bracket in which new frames are being pumped in a restricted nested
40  // run loop.
41  void BeginPumpingFrames();
42  void EndPumpingFrames();
43
44  void GotAcceleratedFrame(
45      uint64 surface_handle, int output_surface_id,
46      const std::vector<ui::LatencyInfo>& latency_info,
47      gfx::Size pixel_size, float scale_factor);
48
49  void GotSoftwareFrame(
50      cc::SoftwareFrameData* frame_data, float scale_factor, SkCanvas* canvas);
51
52private:
53  // IOSurfaceLayerClient implementation:
54  virtual bool IOSurfaceLayerShouldAckImmediately() const OVERRIDE;
55  virtual void IOSurfaceLayerDidDrawFrame() OVERRIDE;
56  virtual void IOSurfaceLayerHitError() OVERRIDE;
57
58  void GotAcceleratedCAContextFrame(
59      CAContextID ca_context_id, gfx::Size pixel_size, float scale_factor);
60
61  void GotAcceleratedIOSurfaceFrame(
62      IOSurfaceID io_surface_id, gfx::Size pixel_size, float scale_factor);
63
64  // Remove a layer from the heirarchy and destroy it. Because the accelerated
65  // layer types may be replaced by a layer of the same type, the layer to
66  // destroy is parameterized, and, if it is the current layer, the current
67  // layer is reset.
68  void DestroyCAContextLayer(
69      base::scoped_nsobject<CALayerHost> ca_context_layer);
70  void DestroyIOSurfaceLayer(
71      base::scoped_nsobject<IOSurfaceLayer> io_surface_layer);
72  void DestroySoftwareLayer();
73
74  // The client of the BrowserCompositorViewMac that is using this as its
75  // internals.
76  BrowserCompositorViewMacClient* client_;
77
78  // A phony NSView handle used to identify this.
79  gfx::AcceleratedWidget native_widget_;
80
81  // The compositor drawing the contents of this view.
82  scoped_ptr<ui::Compositor> compositor_;
83
84  // A flipped layer, which acts as the parent of the compositing and software
85  // layers. This layer is flipped so that the we don't need to recompute the
86  // origin for sub-layers when their position changes (this is impossible when
87  // using remote layers, as their size change cannot be synchronized with the
88  // window). This indirection is needed because flipping hosted layers (like
89  // |background_layer_| of RenderWidgetHostViewCocoa) leads to unpredictable
90  // behavior.
91  base::scoped_nsobject<CALayer> flipped_layer_;
92
93  // The accelerated CoreAnimation layer hosted by the GPU process.
94  base::scoped_nsobject<CALayerHost> ca_context_layer_;
95
96  // The locally drawn accelerated CoreAnimation layer.
97  base::scoped_nsobject<IOSurfaceLayer> io_surface_layer_;
98
99  // The locally drawn software layer.
100  base::scoped_nsobject<SoftwareLayer> software_layer_;
101
102  // The output surface and latency info of the last accelerated surface that
103  // was swapped. Sent back to the renderer when the accelerated surface is
104  // drawn.
105  int accelerated_output_surface_id_;
106  std::vector<ui::LatencyInfo> accelerated_latency_info_;
107
108  // The size in DIP of the last swap received from |compositor_|.
109  gfx::Size last_swap_size_dip_;
110};
111
112}  // namespace content
113
114#endif  // CONTENT_BROWSER_COMPOSITOR_BROWSER_COMPOSITOR_VIEW_PRIVATE_MAC_H_
115