1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#ifndef __INTEL_FRONTBUFFER_H__
25#define __INTEL_FRONTBUFFER_H__
26
27#include <linux/atomic.h>
28#include <linux/kref.h>
29
30#include "gem/i915_gem_object_types.h"
31#include "i915_active.h"
32
33struct drm_i915_private;
34
35enum fb_op_origin {
36 ORIGIN_GTT,
37 ORIGIN_CPU,
38 ORIGIN_CS,
39 ORIGIN_FLIP,
40 ORIGIN_DIRTYFB,
41 ORIGIN_CURSOR_UPDATE,
42};
43
44struct intel_frontbuffer {
45 struct kref ref;
46 atomic_t bits;
47 struct i915_active write;
48 struct drm_i915_gem_object *obj;
49 struct rcu_head rcu;
50};
51
52void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
53 unsigned frontbuffer_bits);
54void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
55 unsigned frontbuffer_bits);
56void intel_frontbuffer_flip(struct drm_i915_private *i915,
57 unsigned frontbuffer_bits);
58
59void intel_frontbuffer_put(struct intel_frontbuffer *front);
60
61static inline struct intel_frontbuffer *
62__intel_frontbuffer_get(const struct drm_i915_gem_object *obj)
63{
64 struct intel_frontbuffer *front;
65
66 if (likely(!rcu_access_pointer(obj->frontbuffer)))
67 return NULL;
68
69 rcu_read_lock();
70 do {
71 front = rcu_dereference(obj->frontbuffer);
72 if (!front)
73 break;
74
75 if (unlikely(!kref_get_unless_zero(&front->ref)))
76 continue;
77
78 if (likely(front == rcu_access_pointer(obj->frontbuffer)))
79 break;
80
81 intel_frontbuffer_put(front);
82 } while (1);
83 rcu_read_unlock();
84
85 return front;
86}
87
88struct intel_frontbuffer *
89intel_frontbuffer_get(struct drm_i915_gem_object *obj);
90
91void __intel_fb_invalidate(struct intel_frontbuffer *front,
92 enum fb_op_origin origin,
93 unsigned int frontbuffer_bits);
94
95
96
97
98
99
100
101
102
103
104
105
106static inline bool intel_frontbuffer_invalidate(struct intel_frontbuffer *front,
107 enum fb_op_origin origin)
108{
109 unsigned int frontbuffer_bits;
110
111 if (!front)
112 return false;
113
114 frontbuffer_bits = atomic_read(&front->bits);
115 if (!frontbuffer_bits)
116 return false;
117
118 __intel_fb_invalidate(front, origin, frontbuffer_bits);
119 return true;
120}
121
122void __intel_fb_flush(struct intel_frontbuffer *front,
123 enum fb_op_origin origin,
124 unsigned int frontbuffer_bits);
125
126
127
128
129
130
131
132
133
134static inline void intel_frontbuffer_flush(struct intel_frontbuffer *front,
135 enum fb_op_origin origin)
136{
137 unsigned int frontbuffer_bits;
138
139 if (!front)
140 return;
141
142 frontbuffer_bits = atomic_read(&front->bits);
143 if (!frontbuffer_bits)
144 return;
145
146 __intel_fb_flush(front, origin, frontbuffer_bits);
147}
148
149void intel_frontbuffer_track(struct intel_frontbuffer *old,
150 struct intel_frontbuffer *new,
151 unsigned int frontbuffer_bits);
152
153#endif
154