drm_framebuffer.h 9.8 KB
Newer Older
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
/*
 * Copyright (c) 2016 Intel Corporation
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that copyright
 * notice and this permission notice appear in supporting documentation, and
 * that the name of the copyright holders not be used in advertising or
 * publicity pertaining to distribution of the software without specific,
 * written prior permission.  The copyright holders make no representations
 * about the suitability of this software for any purpose.  It is provided "as
 * is" without express or implied warranty.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 * OF THIS SOFTWARE.
 */

#ifndef __DRM_FRAMEBUFFER_H__
#define __DRM_FRAMEBUFFER_H__

#include <linux/list.h>
#include <linux/ctype.h>
28
#include <drm/drm_mode_object.h>
29 30 31 32 33 34 35 36 37 38 39 40 41 42

struct drm_framebuffer;
struct drm_file;
struct drm_device;

/**
 * struct drm_framebuffer_funcs - framebuffer hooks
 */
struct drm_framebuffer_funcs {
	/**
	 * @destroy:
	 *
	 * Clean up framebuffer resources, specifically also unreference the
	 * backing storage. The core guarantees to call this function for every
43 44
	 * framebuffer successfully created by calling
	 * &drm_mode_config_funcs.fb_create. Drivers must also call
45 46 47 48 49 50 51 52 53
	 * drm_framebuffer_cleanup() to release DRM core resources for this
	 * framebuffer.
	 */
	void (*destroy)(struct drm_framebuffer *framebuffer);

	/**
	 * @create_handle:
	 *
	 * Create a buffer handle in the driver-specific buffer manager (either
54
	 * GEM or TTM) valid for the passed-in &struct drm_file. This is used by
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
	 * the core to implement the GETFB IOCTL, which returns (for
	 * sufficiently priviledged user) also a native buffer handle. This can
	 * be used for seamless transitions between modesetting clients by
	 * copying the current screen contents to a private buffer and blending
	 * between that and the new contents.
	 *
	 * GEM based drivers should call drm_gem_handle_create() to create the
	 * handle.
	 *
	 * RETURNS:
	 *
	 * 0 on success or a negative error code on failure.
	 */
	int (*create_handle)(struct drm_framebuffer *fb,
			     struct drm_file *file_priv,
			     unsigned int *handle);
	/**
	 * @dirty:
	 *
	 * Optional callback for the dirty fb IOCTL.
	 *
	 * Userspace can notify the driver via this callback that an area of the
	 * framebuffer has changed and should be flushed to the display
	 * hardware. This can also be used internally, e.g. by the fbdev
	 * emulation, though that's not the case currently.
	 *
	 * See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd
	 * for more information as all the semantics and arguments have a one to
	 * one mapping on this function.
	 *
	 * RETURNS:
	 *
	 * 0 on success or a negative error code on failure.
	 */
	int (*dirty)(struct drm_framebuffer *framebuffer,
		     struct drm_file *file_priv, unsigned flags,
		     unsigned color, struct drm_clip_rect *clips,
		     unsigned num_clips);
};

95 96 97 98 99 100 101 102 103
/**
 * struct drm_framebuffer - frame buffer object
 *
 * Note that the fb is refcounted for the benefit of driver internals,
 * for example some hw, disabling a CRTC/plane is asynchronous, and
 * scanout does not actually complete until the next vblank.  So some
 * cleanup (like releasing the reference(s) on the backing GEM bo(s))
 * should be deferred.  In cases like this, the driver would like to
 * hold a ref to the fb even though it has already been removed from
104 105
 * userspace perspective. See drm_framebuffer_get() and
 * drm_framebuffer_put().
106 107 108
 *
 * The refcount is stored inside the mode object @base.
 */
109
struct drm_framebuffer {
110 111 112
	/**
	 * @dev: DRM device this framebuffer belongs to
	 */
113
	struct drm_device *dev;
114
	/**
115 116
	 * @head: Place on the &drm_mode_config.fb_list, access protected by
	 * &drm_mode_config.fb_lock.
117 118
	 */
	struct list_head head;
119 120 121 122

	/**
	 * @base: base modeset object structure, contains the reference count.
	 */
123
	struct drm_mode_object base;
124 125 126 127
	/**
	 * @format: framebuffer format information
	 */
	const struct drm_format_info *format;
128 129 130
	/**
	 * @funcs: framebuffer vfunc table
	 */
131
	const struct drm_framebuffer_funcs *funcs;
132 133 134 135
	/**
	 * @pitches: Line stride per buffer. For userspace created object this
	 * is copied from drm_mode_fb_cmd2.
	 */
136
	unsigned int pitches[4];
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
	/**
	 * @offsets: Offset from buffer start to the actual pixel data in bytes,
	 * per buffer. For userspace created object this is copied from
	 * drm_mode_fb_cmd2.
	 *
	 * Note that this is a linear offset and does not take into account
	 * tiling or buffer laytou per @modifier. It meant to be used when the
	 * actual pixel data for this framebuffer plane starts at an offset,
	 * e.g.  when multiple planes are allocated within the same backing
	 * storage buffer object. For tiled layouts this generally means it
	 * @offsets must at least be tile-size aligned, but hardware often has
	 * stricter requirements.
	 *
	 * This should not be used to specifiy x/y pixel offsets into the buffer
	 * data (even for linear buffers). Specifying an x/y pixel offset is
152
	 * instead done through the source rectangle in &struct drm_plane_state.
153
	 */
154
	unsigned int offsets[4];
155
	/**
V
Ville Syrjälä 已提交
156
	 * @modifier: Data layout modifier. This is used to describe
157 158 159 160
	 * tiling, or also special layouts (like compression) of auxiliary
	 * buffers. For userspace created object this is copied from
	 * drm_mode_fb_cmd2.
	 */
V
Ville Syrjälä 已提交
161
	uint64_t modifier;
162 163 164 165
	/**
	 * @width: Logical width of the visible area of the framebuffer, in
	 * pixels.
	 */
166
	unsigned int width;
167 168 169 170
	/**
	 * @height: Logical height of the visible area of the framebuffer, in
	 * pixels.
	 */
171
	unsigned int height;
172 173 174 175
	/**
	 * @flags: Framebuffer flags like DRM_MODE_FB_INTERLACED or
	 * DRM_MODE_FB_MODIFIERS.
	 */
176
	int flags;
177 178 179 180 181
	/**
	 * @hot_x: X coordinate of the cursor hotspot. Used by the legacy cursor
	 * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR
	 * universal plane.
	 */
182
	int hot_x;
183 184 185 186 187
	/**
	 * @hot_y: Y coordinate of the cursor hotspot. Used by the legacy cursor
	 * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR
	 * universal plane.
	 */
188
	int hot_y;
189
	/**
190
	 * @filp_head: Placed on &drm_file.fbs, protected by &drm_file.fbs_lock.
191
	 */
192
	struct list_head filp_head;
193 194 195 196 197 198 199
	/**
	 * @obj: GEM objects backing the framebuffer, one per plane (optional).
	 *
	 * This is used by the GEM framebuffer helpers, see e.g.
	 * drm_gem_fb_create().
	 */
	struct drm_gem_object *obj[4];
200 201
};

202 203
#define obj_to_fb(x) container_of(x, struct drm_framebuffer, base)

204 205 206 207 208 209 210 211 212 213
int drm_framebuffer_init(struct drm_device *dev,
			 struct drm_framebuffer *fb,
			 const struct drm_framebuffer_funcs *funcs);
struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
					       uint32_t id);
void drm_framebuffer_remove(struct drm_framebuffer *fb);
void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);

/**
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
 * drm_framebuffer_get - acquire a framebuffer reference
 * @fb: DRM framebuffer
 *
 * This function increments the framebuffer's reference count.
 */
static inline void drm_framebuffer_get(struct drm_framebuffer *fb)
{
	drm_mode_object_get(&fb->base);
}

/**
 * drm_framebuffer_put - release a framebuffer reference
 * @fb: DRM framebuffer
 *
 * This function decrements the framebuffer's reference count and frees the
 * framebuffer if the reference count drops to zero.
 */
static inline void drm_framebuffer_put(struct drm_framebuffer *fb)
{
	drm_mode_object_put(&fb->base);
}

/**
 * drm_framebuffer_reference - acquire a framebuffer reference
 * @fb: DRM framebuffer
239
 *
240 241
 * This is a compatibility alias for drm_framebuffer_get() and should not be
 * used by new code.
242 243 244
 */
static inline void drm_framebuffer_reference(struct drm_framebuffer *fb)
{
245
	drm_framebuffer_get(fb);
246 247 248
}

/**
249 250
 * drm_framebuffer_unreference - release a framebuffer reference
 * @fb: DRM framebuffer
251
 *
252 253
 * This is a compatibility alias for drm_framebuffer_put() and should not be
 * used by new code.
254 255 256
 */
static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb)
{
257
	drm_framebuffer_put(fb);
258 259 260 261 262 263 264 265 266 267
}

/**
 * drm_framebuffer_read_refcount - read the framebuffer reference count.
 * @fb: framebuffer
 *
 * This functions returns the framebuffer's reference count.
 */
static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb)
{
268
	return kref_read(&fb->base.refcount);
269
}
270 271

/**
272 273 274 275 276 277 278 279 280 281 282
 * drm_framebuffer_assign - store a reference to the fb
 * @p: location to store framebuffer
 * @fb: new framebuffer (maybe NULL)
 *
 * This functions sets the location to store a reference to the framebuffer,
 * unreferencing the framebuffer that was previously stored in that location.
 */
static inline void drm_framebuffer_assign(struct drm_framebuffer **p,
					  struct drm_framebuffer *fb)
{
	if (fb)
283
		drm_framebuffer_get(fb);
284
	if (*p)
285
		drm_framebuffer_put(*p);
286 287 288 289
	*p = fb;
}

/*
290 291 292 293
 * drm_for_each_fb - iterate over all framebuffers
 * @fb: the loop cursor
 * @dev: the DRM device
 *
294 295
 * Iterate over all framebuffers of @dev. User must hold
 * &drm_mode_config.fb_lock.
296 297 298 299 300 301 302
 */
#define drm_for_each_fb(fb, dev) \
	for (WARN_ON(!mutex_is_locked(&(dev)->mode_config.fb_lock)),		\
	     fb = list_first_entry(&(dev)->mode_config.fb_list,	\
					  struct drm_framebuffer, head);	\
	     &fb->head != (&(dev)->mode_config.fb_list);			\
	     fb = list_next_entry(fb, head))
303 304 305 306 307 308

int drm_framebuffer_plane_width(int width,
				const struct drm_framebuffer *fb, int plane);
int drm_framebuffer_plane_height(int height,
				 const struct drm_framebuffer *fb, int plane);

309
#endif