drm_framebuffer.h 8.9 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 43 44 45 46 47 48 49 50 51 52 53 54 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

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
	 * framebuffer successfully created by ->fb_create() in
	 * &drm_mode_config_funcs. Drivers must also call
	 * 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
	 * GEM or TTM) valid for the passed-in struct &drm_file. This is used by
	 * 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 104 105 106 107 108
/**
 * 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
 * userspace perspective. See drm_framebuffer_reference() and
 * drm_framebuffer_unreference().
 *
 * 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
	/**
	 * @head: Place on the dev->mode_config.fb_list, access protected by
116 117 118
	 * dev->mode_config.fb_lock.
	 */
	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
	/**
	 * @funcs: framebuffer vfunc table
	 */
127
	const struct drm_framebuffer_funcs *funcs;
128 129 130 131
	/**
	 * @pitches: Line stride per buffer. For userspace created object this
	 * is copied from drm_mode_fb_cmd2.
	 */
132
	unsigned int pitches[4];
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
	/**
	 * @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
	 * instead done through the source rectangle in struct &drm_plane_state.
	 */
150
	unsigned int offsets[4];
151 152 153 154 155 156
	/**
	 * @modifier: Data layout modifier, per buffer. This is used to describe
	 * tiling, or also special layouts (like compression) of auxiliary
	 * buffers. For userspace created object this is copied from
	 * drm_mode_fb_cmd2.
	 */
157
	uint64_t modifier[4];
158 159 160 161
	/**
	 * @width: Logical width of the visible area of the framebuffer, in
	 * pixels.
	 */
162
	unsigned int width;
163 164 165 166
	/**
	 * @height: Logical height of the visible area of the framebuffer, in
	 * pixels.
	 */
167
	unsigned int height;
168 169 170 171 172
	/**
	 * @depth: Depth in bits per pixel for RGB formats. 0 for everything
	 * else. Legacy information derived from @pixel_format, it's suggested to use
	 * the DRM FOURCC codes and helper functions directly instead.
	 */
173
	unsigned int depth;
174 175 176 177 178 179
	/**
	 * @bits_per_pixel: Storage used bits per pixel for RGB formats. 0 for
	 * everything else. Legacy information derived from @pixel_format, it's
	 * suggested to use the DRM FOURCC codes and helper functions directly
	 * instead.
	 */
180
	int bits_per_pixel;
181 182 183 184
	/**
	 * @flags: Framebuffer flags like DRM_MODE_FB_INTERLACED or
	 * DRM_MODE_FB_MODIFIERS.
	 */
185
	int flags;
186 187 188
	/**
	 * @pixel_format: DRM FOURCC code describing the pixel format.
	 */
189
	uint32_t pixel_format; /* fourcc format */
190 191 192 193 194
	/**
	 * @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.
	 */
195
	int hot_x;
196 197 198 199 200
	/**
	 * @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.
	 */
201
	int hot_y;
202 203 204 205
	/**
	 * @filp_head: Placed on struct &drm_file fbs list_head, protected by
	 * fbs_lock in the same structure.
	 */
206 207 208
	struct list_head filp_head;
};

209 210
#define obj_to_fb(x) container_of(x, struct drm_framebuffer, base)

211 212 213 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 239 240 241 242 243 244 245 246 247 248 249 250 251
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);

/**
 * drm_framebuffer_reference - incr the fb refcnt
 * @fb: framebuffer
 *
 * This functions increments the fb's refcount.
 */
static inline void drm_framebuffer_reference(struct drm_framebuffer *fb)
{
	drm_mode_object_reference(&fb->base);
}

/**
 * drm_framebuffer_unreference - unref a framebuffer
 * @fb: framebuffer to unref
 *
 * This functions decrements the fb's refcount and frees it if it drops to zero.
 */
static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb)
{
	drm_mode_object_unreference(&fb->base);
}

/**
 * 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)
{
	return atomic_read(&fb->base.refcount.refcount);
}
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266

/**
 * drm_for_each_fb - iterate over all framebuffers
 * @fb: the loop cursor
 * @dev: the DRM device
 *
 * Iterate over all framebuffers of @dev. User must hold the fb_lock from
 * &drm_mode_config.
 */
#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))
267
#endif