0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #ifndef __INTEL_FRONTBUFFER_H__
0025 #define __INTEL_FRONTBUFFER_H__
0026
0027 #include <linux/atomic.h>
0028 #include <linux/kref.h>
0029
0030 #include "gem/i915_gem_object_types.h"
0031 #include "i915_active_types.h"
0032
0033 struct drm_i915_private;
0034
0035 enum fb_op_origin {
0036 ORIGIN_CPU = 0,
0037 ORIGIN_CS,
0038 ORIGIN_FLIP,
0039 ORIGIN_DIRTYFB,
0040 ORIGIN_CURSOR_UPDATE,
0041 };
0042
0043 struct intel_frontbuffer {
0044 struct kref ref;
0045 atomic_t bits;
0046 struct i915_active write;
0047 struct drm_i915_gem_object *obj;
0048 struct rcu_head rcu;
0049 };
0050
0051 void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
0052 unsigned frontbuffer_bits);
0053 void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
0054 unsigned frontbuffer_bits);
0055 void intel_frontbuffer_flip(struct drm_i915_private *i915,
0056 unsigned frontbuffer_bits);
0057
0058 void intel_frontbuffer_put(struct intel_frontbuffer *front);
0059
0060 static inline struct intel_frontbuffer *
0061 __intel_frontbuffer_get(const struct drm_i915_gem_object *obj)
0062 {
0063 struct intel_frontbuffer *front;
0064
0065 if (likely(!rcu_access_pointer(obj->frontbuffer)))
0066 return NULL;
0067
0068 rcu_read_lock();
0069 do {
0070 front = rcu_dereference(obj->frontbuffer);
0071 if (!front)
0072 break;
0073
0074 if (unlikely(!kref_get_unless_zero(&front->ref)))
0075 continue;
0076
0077 if (likely(front == rcu_access_pointer(obj->frontbuffer)))
0078 break;
0079
0080 intel_frontbuffer_put(front);
0081 } while (1);
0082 rcu_read_unlock();
0083
0084 return front;
0085 }
0086
0087 struct intel_frontbuffer *
0088 intel_frontbuffer_get(struct drm_i915_gem_object *obj);
0089
0090 void __intel_fb_invalidate(struct intel_frontbuffer *front,
0091 enum fb_op_origin origin,
0092 unsigned int frontbuffer_bits);
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 static inline bool intel_frontbuffer_invalidate(struct intel_frontbuffer *front,
0106 enum fb_op_origin origin)
0107 {
0108 unsigned int frontbuffer_bits;
0109
0110 if (!front)
0111 return false;
0112
0113 frontbuffer_bits = atomic_read(&front->bits);
0114 if (!frontbuffer_bits)
0115 return false;
0116
0117 __intel_fb_invalidate(front, origin, frontbuffer_bits);
0118 return true;
0119 }
0120
0121 void __intel_fb_flush(struct intel_frontbuffer *front,
0122 enum fb_op_origin origin,
0123 unsigned int frontbuffer_bits);
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 static inline void intel_frontbuffer_flush(struct intel_frontbuffer *front,
0134 enum fb_op_origin origin)
0135 {
0136 unsigned int frontbuffer_bits;
0137
0138 if (!front)
0139 return;
0140
0141 frontbuffer_bits = atomic_read(&front->bits);
0142 if (!frontbuffer_bits)
0143 return;
0144
0145 __intel_fb_flush(front, origin, frontbuffer_bits);
0146 }
0147
0148 void intel_frontbuffer_track(struct intel_frontbuffer *old,
0149 struct intel_frontbuffer *new,
0150 unsigned int frontbuffer_bits);
0151
0152 #endif