summaryrefslogtreecommitdiffstats
path: root/cc/output/output_surface.h
blob: bb6a59e7ecde237fe827fcd91af98d53454a34ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_OUTPUT_OUTPUT_SURFACE_H_
#define CC_OUTPUT_OUTPUT_SURFACE_H_

#include <deque>

#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "cc/base/cc_export.h"
#include "cc/output/context_provider.h"
#include "cc/output/overlay_candidate_validator.h"
#include "cc/output/software_output_device.h"

namespace base { class SingleThreadTaskRunner; }

namespace ui {
class LatencyInfo;
}

namespace gfx {
class Rect;
class Size;
class Transform;
}

namespace cc {

class CompositorFrame;
class CompositorFrameAck;
struct ManagedMemoryPolicy;
class OutputSurfaceClient;

// Represents the output surface for a compositor. The compositor owns
// and manages its destruction. Its lifetime is:
//   1. Created on the main thread by the LayerTreeHost through its client.
//   2. Passed to the compositor thread and bound to a client via BindToClient.
//      From here on, it will only be used on the compositor thread.
//   3. If the 3D context is lost, then the compositor will delete the output
//      surface (on the compositor thread) and go back to step 1.
class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider {
 public:
  enum {
    DEFAULT_MAX_FRAMES_PENDING = 2
  };

  OutputSurface(const scoped_refptr<ContextProvider>& context_provider,
                const scoped_refptr<ContextProvider>& worker_context_provider,
                scoped_ptr<SoftwareOutputDevice> software_device);
  OutputSurface(const scoped_refptr<ContextProvider>& context_provider,
                const scoped_refptr<ContextProvider>& worker_context_provider);
  explicit OutputSurface(
      const scoped_refptr<ContextProvider>& context_provider);

  explicit OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device);

  OutputSurface(const scoped_refptr<ContextProvider>& context_provider,
                scoped_ptr<SoftwareOutputDevice> software_device);

  ~OutputSurface() override;

  struct Capabilities {
    Capabilities()
        : delegated_rendering(false),
          max_frames_pending(0),
          draw_and_swap_full_viewport_every_frame(false),
          adjust_deadline_for_parent(true),
          uses_default_gl_framebuffer(true),
          flipped_output_surface(false),
          can_force_reclaim_resources(false),
          delegated_sync_points_required(true) {}
    bool delegated_rendering;
    int max_frames_pending;
    bool draw_and_swap_full_viewport_every_frame;
    // This doesn't handle the <webview> case, but once BeginFrame is
    // supported natively, we shouldn't need adjust_deadline_for_parent.
    bool adjust_deadline_for_parent;
    // Whether this output surface renders to the default OpenGL zero
    // framebuffer or to an offscreen framebuffer.
    bool uses_default_gl_framebuffer;
    // Whether this OutputSurface is flipped or not.
    bool flipped_output_surface;
    // Whether ForceReclaimResources can be called to reclaim all resources
    // from the OutputSurface.
    bool can_force_reclaim_resources;
    // True if sync points for resources are needed when swapping delegated
    // frames.
    bool delegated_sync_points_required;
  };

  const Capabilities& capabilities() const {
    return capabilities_;
  }

  virtual bool HasExternalStencilTest() const;

  // Obtain the 3d context or the software device associated with this output
  // surface. Either of these may return a null pointer, but not both.
  // In the event of a lost context, the entire output surface should be
  // recreated.
  ContextProvider* context_provider() const { return context_provider_.get(); }
  ContextProvider* worker_context_provider() const {
    return worker_context_provider_.get();
  }
  SoftwareOutputDevice* software_device() const {
    return software_device_.get();
  }

  // Called by the compositor on the compositor thread. This is a place where
  // thread-specific data for the output surface can be initialized, since from
  // this point to when DetachFromClient() is called the output surface will
  // only be used on the compositor thread.
  virtual bool BindToClient(OutputSurfaceClient* client);

  // Called by the compositor on the compositor thread. This is a place where
  // thread-specific data for the output surface can be uninitialized.
  virtual void DetachFromClient();

  virtual void EnsureBackbuffer();
  virtual void DiscardBackbuffer();

  virtual void Reshape(const gfx::Size& size, float scale_factor);
  gfx::Size SurfaceSize() const { return surface_size_; }
  float device_scale_factor() const { return device_scale_factor_; }

  // If supported, this causes a ReclaimResources for all resources that are
  // currently in use.
  virtual void ForceReclaimResources() {}

  virtual void BindFramebuffer();

  // The implementation may destroy or steal the contents of the CompositorFrame
  // passed in (though it will not take ownership of the CompositorFrame
  // itself). For successful swaps, the implementation must call
  // OutputSurfaceClient::DidSwapBuffers() and eventually
  // DidSwapBuffersComplete().
  virtual void SwapBuffers(CompositorFrame* frame) = 0;
  virtual void OnSwapBuffersComplete();

  // Notifies frame-rate smoothness preference. If true, all non-critical
  // processing should be stopped, or lowered in priority.
  virtual void UpdateSmoothnessTakesPriority(bool prefer_smoothness) {}

  bool HasClient() { return !!client_; }

  // Get the class capable of informing cc of hardware overlay capability.
  virtual OverlayCandidateValidator* GetOverlayCandidateValidator() const;

  // Returns true if a main image overlay plane should be scheduled.
  virtual bool IsDisplayedAsOverlayPlane() const;

  // Get the texture for the main image's overlay.
  virtual unsigned GetOverlayTextureId() const;

  void DidLoseOutputSurface();
  void SetMemoryPolicy(const ManagedMemoryPolicy& policy);

  // Support for a pull-model where draws are requested by the output surface.
  //
  // OutputSurface::Invalidate is called by the compositor to notify that
  // there's new content.
  virtual void Invalidate() {}

  // Updates the worker context provider's visibility, freeing GPU resources if
  // appropriate.
  virtual void SetWorkerContextShouldAggressivelyFreeResources(bool is_visible);

  // If this returns true, then the surface will not attempt to draw.
  virtual bool SurfaceIsSuspendForRecycle() const;

  // base::trace_event::MemoryDumpProvider implementation.
  bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
                    base::trace_event::ProcessMemoryDump* pmd) override;

 protected:
  OutputSurfaceClient* client_;

  void PostSwapBuffersComplete();

  struct OutputSurface::Capabilities capabilities_;
  scoped_refptr<ContextProvider> context_provider_;
  scoped_refptr<ContextProvider> worker_context_provider_;
  scoped_ptr<SoftwareOutputDevice> software_device_;
  gfx::Size surface_size_;
  float device_scale_factor_;
  base::ThreadChecker client_thread_checker_;

  void CommitVSyncParameters(base::TimeTicks timebase,
                             base::TimeDelta interval);

  void SetNeedsRedrawRect(const gfx::Rect& damage_rect);
  void ReclaimResources(const CompositorFrameAck* ack);
  void SetExternalStencilTest(bool enabled);
  void SetExternalDrawConstraints(
      const gfx::Transform& transform,
      const gfx::Rect& viewport,
      const gfx::Rect& clip,
      const gfx::Rect& viewport_rect_for_tile_priority,
      const gfx::Transform& transform_for_tile_priority,
      bool resourceless_software_draw);
  void DetachFromClientInternal();

 private:
  bool external_stencil_test_enabled_;

  base::WeakPtrFactory<OutputSurface> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(OutputSurface);
};

}  // namespace cc

#endif  // CC_OUTPUT_OUTPUT_SURFACE_H_