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};
42
43struct intel_frontbuffer {
44 struct kref ref;
45 atomic_t bits;
46 struct i915_active write;
47 struct drm_i915_gem_object *obj;
48 struct rcu_head rcu;
49};
50
51void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
52 unsigned frontbuffer_bits);
53void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
54 unsigned frontbuffer_bits);
55void intel_frontbuffer_flip(struct drm_i915_private *i915,
56 unsigned frontbuffer_bits);
57
58void intel_frontbuffer_put(struct intel_frontbuffer *front);
59
60static inline struct intel_frontbuffer *
61__intel_frontbuffer_get(const struct drm_i915_gem_object *obj)
62{
63 struct intel_frontbuffer *front;
64
65 if (likely(!rcu_access_pointer(obj->frontbuffer)))
66 return NULL;
67
68 rcu_read_lock();
69 do {
70 front = rcu_dereference(obj->frontbuffer);
71 if (!front)
72 break;
73
74 if (unlikely(!kref_get_unless_zero(&front->ref)))
75 continue;
76
77 if (likely(front == rcu_access_pointer(obj->frontbuffer)))
78 break;
79
80 intel_frontbuffer_put(front);
81 } while (1);
82 rcu_read_unlock();
83
84 return front;
85}
86
87struct intel_frontbuffer *
88intel_frontbuffer_get(struct drm_i915_gem_object *obj);
89
90void __intel_fb_invalidate(struct intel_frontbuffer *front,
91 enum fb_op_origin origin,
92 unsigned int frontbuffer_bits);
93
94
95
96
97
98
99
100
101
102
103
104
105static inline bool intel_frontbuffer_invalidate(struct intel_frontbuffer *front,
106 enum fb_op_origin origin)
107{
108 unsigned int frontbuffer_bits;
109
110 if (!front)
111 return false;
112
113 frontbuffer_bits = atomic_read(&front->bits);
114 if (!frontbuffer_bits)
115 return false;
116
117 __intel_fb_invalidate(front, origin, frontbuffer_bits);
118 return true;
119}
120
121void __intel_fb_flush(struct intel_frontbuffer *front,
122 enum fb_op_origin origin,
123 unsigned int frontbuffer_bits);
124
125
126
127
128
129
130
131
132
133static inline void intel_frontbuffer_flush(struct intel_frontbuffer *front,
134 enum fb_op_origin origin)
135{
136 unsigned int frontbuffer_bits;
137
138 if (!front)
139 return;
140
141 frontbuffer_bits = atomic_read(&front->bits);
142 if (!frontbuffer_bits)
143 return;
144
145 __intel_fb_flush(front, origin, frontbuffer_bits);
146}
147
148void intel_frontbuffer_track(struct intel_frontbuffer *old,
149 struct intel_frontbuffer *new,
150 unsigned int frontbuffer_bits);
151
152#endif
153