Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2014-2016 Intel Corporation
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice (including the next
0012  * paragraph) shall be included in all copies or substantial portions of the
0013  * Software.
0014  *
0015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0018  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0020  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
0021  * IN THE SOFTWARE.
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  * intel_frontbuffer_invalidate - invalidate frontbuffer object
0096  * @front: GEM object to invalidate
0097  * @origin: which operation caused the invalidation
0098  *
0099  * This function gets called every time rendering on the given object starts and
0100  * frontbuffer caching (fbc, low refresh rate for DRRS, panel self refresh) must
0101  * be invalidated. For ORIGIN_CS any subsequent invalidation will be delayed
0102  * until the rendering completes or a flip on this frontbuffer plane is
0103  * scheduled.
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  * intel_frontbuffer_flush - flush frontbuffer object
0127  * @front: GEM object to flush
0128  * @origin: which operation caused the flush
0129  *
0130  * This function gets called every time rendering on the given object has
0131  * completed and frontbuffer caching can be started again.
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 /* __INTEL_FRONTBUFFER_H__ */