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
|
// Copyright 2013 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 CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_LAYER_MAC_H_
#define CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_LAYER_MAC_H_
#import <Cocoa/Cocoa.h>
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/ref_counted.h"
#include "base/timer/timer.h"
@class CompositingIOSurfaceLayer;
namespace content {
class CompositingIOSurfaceMac;
class CompositingIOSurfaceContext;
// The interface through which the CompositingIOSurfaceLayer calls back into
// the structrue that created it (RenderWidgetHostViewMac or
// BrowserCompositorViewMac).
class CompositingIOSurfaceLayerClient {
public:
virtual bool AcceleratedLayerShouldAckImmediately() const = 0;
virtual void AcceleratedLayerDidDrawFrame(bool succeeded) = 0;
};
// CompositingIOSurfaceLayerHelper provides C++ functionality needed for the
// CompositingIOSurfaceLayer class, and does most of the heavy lifting for the
// class.
// TODO(ccameron): This class should own CompositingIOSurfaceLayer, rather than
// vice versa.
class CompositingIOSurfaceLayerHelper {
public:
CompositingIOSurfaceLayerHelper(CompositingIOSurfaceLayerClient* client,
CompositingIOSurfaceLayer* layer);
~CompositingIOSurfaceLayerHelper();
// Called when the CompositingIOSurfaceLayer gets a new frame.
void GotNewFrame();
// Called whenever -[CompositingIOSurfaceLayer setNeedsDisplay] is called.
void SetNeedsDisplay();
// Called whenever -[CompositingIOSurfaceLayer canDrawInCGLContext] is called,
// to determine if a new frame should be drawn.
bool CanDraw();
// Called whenever -[CompositingIOSurfaceLayer drawInCGLContext] draws a
// frame.
void DidDraw(bool success);
// Immediately re-draw the layer, even if the content has not changed, and
// ensure that the frame be acked.
void SetNeedsDisplayAndDisplayAndAck();
// Immediately draw the layer, only if one is pending, and ensure that the
// frame be acked.
void DisplayIfNeededAndAck();
// Mark a bracket in which new frames are being pumped in a restricted nested
// run loop. During this time frames are acked immediately and draws are
// deferred until the bracket ends.
void BeginPumpingFrames();
void EndPumpingFrames();
private:
// Called whenever the frame provided in GotNewFrame should be acknowledged
// (this may be because it was drawn, or it may be to unblock the
// compositor).
void AckPendingFrame(bool success);
void TimerFired();
// The client that the owning layer was created with.
content::CompositingIOSurfaceLayerClient* const client_;
// The layer that owns this helper.
CompositingIOSurfaceLayer* const layer_;
// Used to track when canDrawInCGLContext should return YES. This can be
// in response to receiving a new compositor frame, or from any of the events
// that cause setNeedsDisplay to be called on the layer.
bool needs_display_;
// This is set when a frame is received, and un-set when the frame is drawn.
bool has_pending_frame_;
// Incremented every time that this layer is asked to draw but does not have
// new content to draw.
uint64 did_not_draw_counter_;
// Set when inside a BeginPumpingFrames/EndPumpingFrames block.
bool is_pumping_frames_;
// The browser places back-pressure on the GPU by not acknowledging swap
// calls until they appear on the screen. This can lead to hangs if the
// view is moved offscreen (among other things). Prevent hangs by always
// acknowledging the frame after timeout of 1/6th of a second has passed.
base::DelayTimer<CompositingIOSurfaceLayerHelper> timer_;
};
} // namespace content
// The CoreAnimation layer for drawing accelerated content.
@interface CompositingIOSurfaceLayer : CAOpenGLLayer {
@private
scoped_refptr<content::CompositingIOSurfaceMac> iosurface_;
scoped_refptr<content::CompositingIOSurfaceContext> context_;
scoped_ptr<content::CompositingIOSurfaceLayerHelper> helper_;
}
- (content::CompositingIOSurfaceMac*)iosurface;
- (content::CompositingIOSurfaceContext*)context;
- (id)initWithIOSurface:(scoped_refptr<content::CompositingIOSurfaceMac>)
iosurface
withScaleFactor:(float)scale_factor
withClient:(content::CompositingIOSurfaceLayerClient*)client;
// Mark that the client is no longer valid and cannot be called back into. This
// must be called before the layer is destroyed.
- (void)resetClient;
// Called when a new frame is received.
- (void)gotNewFrame;
// Force a draw immediately (even if this means re-displaying a previously
// displayed frame).
- (void)setNeedsDisplayAndDisplayAndAck;
// Force a draw immediately, but only if one was requested.
- (void)displayIfNeededAndAck;
// Mark a bracket in which new frames are being pumped in a restricted nested
// run loop.
- (void)beginPumpingFrames;
- (void)endPumpingFrames;
@end
#endif // CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_LAYER_MAC_H_
|