initial commit
[ubuntu-omap:rsalvetis-xf86-video-omap.git] / src / omap_exa_common.c
1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2
3 /*
4  * Copyright © 2011 Texas Instruments, Inc
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  *
25  * Authors:
26  *    Rob Clark <rob@ti.com>
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "omap_exa_common.h"
34
35 #include "exa.h"
36
37
38 #define pix2scrn(pPixmap) \
39                 xf86Screens[(pPixmap)->drawable.pScreen->myNum]
40
41
42 /* Common OMAP EXA functions, mostly related to pixmap/buffer allocation.
43  * Individual driver submodules can use these directly, or wrap them with
44  * there own functions if anything additional is required.  Submodules
45  * can use OMAPPrixmapPrivPtr#priv for their own private data.
46  */
47
48 void *
49 OMAPCreatePixmap (ScreenPtr pScreen, int width, int height,
50                 int depth, int usage_hint, int bitsPerPixel,
51                 int *new_fb_pitch)
52 {
53         OMAPPixmapPrivPtr priv = calloc(sizeof(OMAPPixmapPrivRec), 1);
54
55         /* actual allocation of buffer is in OMAPModifyPixmapHeader */
56
57         return priv;
58 }
59
60 void
61 OMAPDestroyPixmap(ScreenPtr pScreen, void *driverPriv)
62 {
63         OMAPPixmapPrivPtr priv = driverPriv;
64
65         if (priv->bo) {
66                 omap_bo_del(priv->bo);
67         }
68
69         free(priv);
70 }
71
72 Bool
73 OMAPModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
74                 int depth, int bitsPerPixel, int devKind,
75                 pointer pPixData)
76 {
77         OMAPPixmapPrivPtr priv = exaGetPixmapDriverPrivate(pPixmap);
78         ScrnInfoPtr pScrn = pix2scrn(pPixmap);
79         OMAPPtr pOMAP = OMAPPTR(pScrn);
80         uint32_t size;
81         Bool ret;
82
83         ret = miModifyPixmapHeader(pPixmap, width, height, depth,
84                         bitsPerPixel, devKind, pPixData);
85         if (!ret) {
86                 return ret;
87         }
88
89         if (pPixData == omap_bo_map(pOMAP->scanout)) {
90                 DEBUG_MSG("wrapping scanout buffer");
91                 if (priv->bo != pOMAP->scanout) {
92                         omap_bo_del(priv->bo);
93                         priv->bo = pOMAP->scanout;
94                 }
95                 return TRUE;
96         } else if (pPixData) {
97                 /* we can't accelerate this pixmap, and don't ever want to
98                  * see it again..
99                  */
100                 pPixmap->devPrivate.ptr = pPixData;
101                 pPixmap->devKind = devKind;
102
103                 /* scratch-pixmap (see GetScratchPixmapHeader()) gets recycled,
104                  * so could have a previous bo!
105                  */
106                 omap_bo_del(priv->bo);
107                 priv->bo = NULL;
108
109                 return FALSE;
110         }
111
112         /* passed in values could be zero, indicating that existing values
113          * should be kept.. miModifyPixmapHeader() will deal with that, but
114          * we need to resync to ensure we have the right values in the rest
115          * of this function
116          */
117         width   = pPixmap->drawable.width;
118         height  = pPixmap->drawable.height;
119         depth   = pPixmap->drawable.depth;
120         bitsPerPixel = pPixmap->drawable.bitsPerPixel;
121
122
123         pPixmap->devKind = OMAPCalculateStride(width, bitsPerPixel);
124         size = pPixmap->devKind * height;
125
126         if ((!priv->bo) || (omap_bo_size(priv->bo) != size)) {
127                 /* re-allocate buffer! */
128                 omap_bo_del(priv->bo);
129                 priv->bo = omap_bo_new(pOMAP->dev, size, 0);
130         }
131
132         return TRUE;
133 }
134
135 /**
136  * WaitMarker is a required EXA callback but synchronization is
137  * performed during OMAPPrepareAccess so this function does not
138  * have anything to do at present
139  */
140 void
141 OMAPWaitMarker(ScreenPtr pScreen, int marker)
142 {
143         /* no-op */
144 }
145
146 /**
147  * PrepareAccess() is called before CPU access to an offscreen pixmap.
148  *
149  * @param pPix the pixmap being accessed
150  * @param index the index of the pixmap being accessed.
151  *
152  * PrepareAccess() will be called before CPU access to an offscreen pixmap.
153  * This can be used to set up hardware surfaces for byteswapping or
154  * untiling, or to adjust the pixmap's devPrivate.ptr for the purpose of
155  * making CPU access use a different aperture.
156  *
157  * The index is one of #EXA_PREPARE_DEST, #EXA_PREPARE_SRC,
158  * #EXA_PREPARE_MASK, #EXA_PREPARE_AUX_DEST, #EXA_PREPARE_AUX_SRC, or
159  * #EXA_PREPARE_AUX_MASK. Since only up to #EXA_NUM_PREPARE_INDICES pixmaps
160  * will have PrepareAccess() called on them per operation, drivers can have
161  * a small, statically-allocated space to maintain state for PrepareAccess()
162  * and FinishAccess() in.  Note that PrepareAccess() is only called once per
163  * pixmap and operation, regardless of whether the pixmap is used as a
164  * destination and/or source, and the index may not reflect the usage.
165  *
166  * PrepareAccess() may fail.  An example might be the case of hardware that
167  * can set up 1 or 2 surfaces for CPU access, but not 3.  If PrepareAccess()
168  * fails, EXA will migrate the pixmap to system memory.
169  * DownloadFromScreen() must be implemented and must not fail if a driver
170  * wishes to fail in PrepareAccess().  PrepareAccess() must not fail when
171  * pPix is the visible screen, because the visible screen can not be
172  * migrated.
173  *
174  * @return TRUE if PrepareAccess() successfully prepared the pixmap for CPU
175  * drawing.
176  * @return FALSE if PrepareAccess() is unsuccessful and EXA should use
177  * DownloadFromScreen() to migate the pixmap out.
178  */
179 Bool
180 OMAPPrepareAccess(PixmapPtr pPixmap, int index)
181 {
182         OMAPPixmapPrivPtr priv = exaGetPixmapDriverPrivate(pPixmap);
183
184         /* TODO: wait for blits complete on priv->bo.. */
185
186         pPixmap->devPrivate.ptr = omap_bo_map(priv->bo);
187
188         return TRUE;
189 }
190
191 /**
192  * FinishAccess() is called after CPU access to an offscreen pixmap.
193  *
194  * @param pPix the pixmap being accessed
195  * @param index the index of the pixmap being accessed.
196  *
197  * FinishAccess() will be called after finishing CPU access of an offscreen
198  * pixmap set up by PrepareAccess().  Note that the FinishAccess() will not be
199  * called if PrepareAccess() failed and the pixmap was migrated out.
200  */
201 void
202 OMAPFinishAccess(PixmapPtr pPixmap, int index)
203 {
204         pPixmap->devPrivate.ptr = NULL;
205 }
206
207 /**
208  * PixmapIsOffscreen() is an optional driver replacement to
209  * exaPixmapHasGpuCopy(). Set to NULL if you want the standard behaviour
210  * of exaPixmapHasGpuCopy().
211  *
212  * @param pPix the pixmap
213  * @return TRUE if the given drawable is in framebuffer memory.
214  *
215  * exaPixmapHasGpuCopy() is used to determine if a pixmap is in offscreen
216  * memory, meaning that acceleration could probably be done to it, and that it
217  * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it
218  * with the CPU.
219  */
220 Bool
221 OMAPPixmapIsOffscreen(PixmapPtr pPixmap)
222 {
223         /* offscreen means in 'gpu accessible memory', not that it's off the
224          * visible screen.  We currently have no special constraints, since
225          * OMAP has a flat memory model (no separate GPU memory).  If
226          * individual EXA implementation has additional constraints, like
227          * buffer size or mapping in GPU MMU, it should wrap this function.
228          */
229         OMAPPixmapPrivPtr priv = exaGetPixmapDriverPrivate(pPixmap);
230         return priv && priv->bo;
231 }