Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2016 Intel Corporation
3 : : *
4 : : * Permission to use, copy, modify, distribute, and sell this software and its
5 : : * documentation for any purpose is hereby granted without fee, provided that
6 : : * the above copyright notice appear in all copies and that both that copyright
7 : : * notice and this permission notice appear in supporting documentation, and
8 : : * that the name of the copyright holders not be used in advertising or
9 : : * publicity pertaining to distribution of the software without specific,
10 : : * written prior permission. The copyright holders make no representations
11 : : * about the suitability of this software for any purpose. It is provided "as
12 : : * is" without express or implied warranty.
13 : : *
14 : : * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 : : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 : : * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 : : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 : : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 : : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 : : * OF THIS SOFTWARE.
21 : : */
22 : :
23 : : #ifndef __DRM_FRAMEBUFFER_H__
24 : : #define __DRM_FRAMEBUFFER_H__
25 : :
26 : : #include <linux/ctype.h>
27 : : #include <linux/list.h>
28 : : #include <linux/sched.h>
29 : :
30 : : #include <drm/drm_mode_object.h>
31 : :
32 : : struct drm_clip_rect;
33 : : struct drm_device;
34 : : struct drm_file;
35 : : struct drm_format_info;
36 : : struct drm_framebuffer;
37 : : struct drm_gem_object;
38 : :
39 : : /**
40 : : * struct drm_framebuffer_funcs - framebuffer hooks
41 : : */
42 : : struct drm_framebuffer_funcs {
43 : : /**
44 : : * @destroy:
45 : : *
46 : : * Clean up framebuffer resources, specifically also unreference the
47 : : * backing storage. The core guarantees to call this function for every
48 : : * framebuffer successfully created by calling
49 : : * &drm_mode_config_funcs.fb_create. Drivers must also call
50 : : * drm_framebuffer_cleanup() to release DRM core resources for this
51 : : * framebuffer.
52 : : */
53 : : void (*destroy)(struct drm_framebuffer *framebuffer);
54 : :
55 : : /**
56 : : * @create_handle:
57 : : *
58 : : * Create a buffer handle in the driver-specific buffer manager (either
59 : : * GEM or TTM) valid for the passed-in &struct drm_file. This is used by
60 : : * the core to implement the GETFB IOCTL, which returns (for
61 : : * sufficiently priviledged user) also a native buffer handle. This can
62 : : * be used for seamless transitions between modesetting clients by
63 : : * copying the current screen contents to a private buffer and blending
64 : : * between that and the new contents.
65 : : *
66 : : * GEM based drivers should call drm_gem_handle_create() to create the
67 : : * handle.
68 : : *
69 : : * RETURNS:
70 : : *
71 : : * 0 on success or a negative error code on failure.
72 : : */
73 : : int (*create_handle)(struct drm_framebuffer *fb,
74 : : struct drm_file *file_priv,
75 : : unsigned int *handle);
76 : : /**
77 : : * @dirty:
78 : : *
79 : : * Optional callback for the dirty fb IOCTL.
80 : : *
81 : : * Userspace can notify the driver via this callback that an area of the
82 : : * framebuffer has changed and should be flushed to the display
83 : : * hardware. This can also be used internally, e.g. by the fbdev
84 : : * emulation, though that's not the case currently.
85 : : *
86 : : * See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd
87 : : * for more information as all the semantics and arguments have a one to
88 : : * one mapping on this function.
89 : : *
90 : : * Atomic drivers should use drm_atomic_helper_dirtyfb() to implement
91 : : * this hook.
92 : : *
93 : : * RETURNS:
94 : : *
95 : : * 0 on success or a negative error code on failure.
96 : : */
97 : : int (*dirty)(struct drm_framebuffer *framebuffer,
98 : : struct drm_file *file_priv, unsigned flags,
99 : : unsigned color, struct drm_clip_rect *clips,
100 : : unsigned num_clips);
101 : : };
102 : :
103 : : /**
104 : : * struct drm_framebuffer - frame buffer object
105 : : *
106 : : * Note that the fb is refcounted for the benefit of driver internals,
107 : : * for example some hw, disabling a CRTC/plane is asynchronous, and
108 : : * scanout does not actually complete until the next vblank. So some
109 : : * cleanup (like releasing the reference(s) on the backing GEM bo(s))
110 : : * should be deferred. In cases like this, the driver would like to
111 : : * hold a ref to the fb even though it has already been removed from
112 : : * userspace perspective. See drm_framebuffer_get() and
113 : : * drm_framebuffer_put().
114 : : *
115 : : * The refcount is stored inside the mode object @base.
116 : : */
117 : : struct drm_framebuffer {
118 : : /**
119 : : * @dev: DRM device this framebuffer belongs to
120 : : */
121 : : struct drm_device *dev;
122 : : /**
123 : : * @head: Place on the &drm_mode_config.fb_list, access protected by
124 : : * &drm_mode_config.fb_lock.
125 : : */
126 : : struct list_head head;
127 : :
128 : : /**
129 : : * @base: base modeset object structure, contains the reference count.
130 : : */
131 : : struct drm_mode_object base;
132 : :
133 : : /**
134 : : * @comm: Name of the process allocating the fb, used for fb dumping.
135 : : */
136 : : char comm[TASK_COMM_LEN];
137 : :
138 : : /**
139 : : * @format: framebuffer format information
140 : : */
141 : : const struct drm_format_info *format;
142 : : /**
143 : : * @funcs: framebuffer vfunc table
144 : : */
145 : : const struct drm_framebuffer_funcs *funcs;
146 : : /**
147 : : * @pitches: Line stride per buffer. For userspace created object this
148 : : * is copied from drm_mode_fb_cmd2.
149 : : */
150 : : unsigned int pitches[4];
151 : : /**
152 : : * @offsets: Offset from buffer start to the actual pixel data in bytes,
153 : : * per buffer. For userspace created object this is copied from
154 : : * drm_mode_fb_cmd2.
155 : : *
156 : : * Note that this is a linear offset and does not take into account
157 : : * tiling or buffer laytou per @modifier. It meant to be used when the
158 : : * actual pixel data for this framebuffer plane starts at an offset,
159 : : * e.g. when multiple planes are allocated within the same backing
160 : : * storage buffer object. For tiled layouts this generally means it
161 : : * @offsets must at least be tile-size aligned, but hardware often has
162 : : * stricter requirements.
163 : : *
164 : : * This should not be used to specifiy x/y pixel offsets into the buffer
165 : : * data (even for linear buffers). Specifying an x/y pixel offset is
166 : : * instead done through the source rectangle in &struct drm_plane_state.
167 : : */
168 : : unsigned int offsets[4];
169 : : /**
170 : : * @modifier: Data layout modifier. This is used to describe
171 : : * tiling, or also special layouts (like compression) of auxiliary
172 : : * buffers. For userspace created object this is copied from
173 : : * drm_mode_fb_cmd2.
174 : : */
175 : : uint64_t modifier;
176 : : /**
177 : : * @width: Logical width of the visible area of the framebuffer, in
178 : : * pixels.
179 : : */
180 : : unsigned int width;
181 : : /**
182 : : * @height: Logical height of the visible area of the framebuffer, in
183 : : * pixels.
184 : : */
185 : : unsigned int height;
186 : : /**
187 : : * @flags: Framebuffer flags like DRM_MODE_FB_INTERLACED or
188 : : * DRM_MODE_FB_MODIFIERS.
189 : : */
190 : : int flags;
191 : : /**
192 : : * @hot_x: X coordinate of the cursor hotspot. Used by the legacy cursor
193 : : * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR
194 : : * universal plane.
195 : : */
196 : : int hot_x;
197 : : /**
198 : : * @hot_y: Y coordinate of the cursor hotspot. Used by the legacy cursor
199 : : * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR
200 : : * universal plane.
201 : : */
202 : : int hot_y;
203 : : /**
204 : : * @filp_head: Placed on &drm_file.fbs, protected by &drm_file.fbs_lock.
205 : : */
206 : : struct list_head filp_head;
207 : : /**
208 : : * @obj: GEM objects backing the framebuffer, one per plane (optional).
209 : : *
210 : : * This is used by the GEM framebuffer helpers, see e.g.
211 : : * drm_gem_fb_create().
212 : : */
213 : : struct drm_gem_object *obj[4];
214 : : };
215 : :
216 : : #define obj_to_fb(x) container_of(x, struct drm_framebuffer, base)
217 : :
218 : : int drm_framebuffer_init(struct drm_device *dev,
219 : : struct drm_framebuffer *fb,
220 : : const struct drm_framebuffer_funcs *funcs);
221 : : struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
222 : : struct drm_file *file_priv,
223 : : uint32_t id);
224 : : void drm_framebuffer_remove(struct drm_framebuffer *fb);
225 : : void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
226 : : void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);
227 : :
228 : : /**
229 : : * drm_framebuffer_get - acquire a framebuffer reference
230 : : * @fb: DRM framebuffer
231 : : *
232 : : * This function increments the framebuffer's reference count.
233 : : */
234 : 0 : static inline void drm_framebuffer_get(struct drm_framebuffer *fb)
235 : : {
236 : 0 : drm_mode_object_get(&fb->base);
237 : 0 : }
238 : :
239 : : /**
240 : : * drm_framebuffer_put - release a framebuffer reference
241 : : * @fb: DRM framebuffer
242 : : *
243 : : * This function decrements the framebuffer's reference count and frees the
244 : : * framebuffer if the reference count drops to zero.
245 : : */
246 : 0 : static inline void drm_framebuffer_put(struct drm_framebuffer *fb)
247 : : {
248 : 0 : drm_mode_object_put(&fb->base);
249 : 0 : }
250 : :
251 : : /**
252 : : * drm_framebuffer_read_refcount - read the framebuffer reference count.
253 : : * @fb: framebuffer
254 : : *
255 : : * This functions returns the framebuffer's reference count.
256 : : */
257 : 0 : static inline uint32_t drm_framebuffer_read_refcount(const struct drm_framebuffer *fb)
258 : : {
259 : 0 : return kref_read(&fb->base.refcount);
260 : : }
261 : :
262 : : /**
263 : : * drm_framebuffer_assign - store a reference to the fb
264 : : * @p: location to store framebuffer
265 : : * @fb: new framebuffer (maybe NULL)
266 : : *
267 : : * This functions sets the location to store a reference to the framebuffer,
268 : : * unreferencing the framebuffer that was previously stored in that location.
269 : : */
270 : 0 : static inline void drm_framebuffer_assign(struct drm_framebuffer **p,
271 : : struct drm_framebuffer *fb)
272 : : {
273 [ # # ]: 0 : if (fb)
274 : 0 : drm_framebuffer_get(fb);
275 [ # # ]: 0 : if (*p)
276 : 0 : drm_framebuffer_put(*p);
277 : 0 : *p = fb;
278 : 0 : }
279 : :
280 : : /*
281 : : * drm_for_each_fb - iterate over all framebuffers
282 : : * @fb: the loop cursor
283 : : * @dev: the DRM device
284 : : *
285 : : * Iterate over all framebuffers of @dev. User must hold
286 : : * &drm_mode_config.fb_lock.
287 : : */
288 : : #define drm_for_each_fb(fb, dev) \
289 : : for (WARN_ON(!mutex_is_locked(&(dev)->mode_config.fb_lock)), \
290 : : fb = list_first_entry(&(dev)->mode_config.fb_list, \
291 : : struct drm_framebuffer, head); \
292 : : &fb->head != (&(dev)->mode_config.fb_list); \
293 : : fb = list_next_entry(fb, head))
294 : :
295 : : int drm_framebuffer_plane_width(int width,
296 : : const struct drm_framebuffer *fb, int plane);
297 : : int drm_framebuffer_plane_height(int height,
298 : : const struct drm_framebuffer *fb, int plane);
299 : :
300 : : #endif
|