2 * Copyright © 2009 Maarten Maathuis
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 #ifdef HAVE_DIX_CONFIG_H
26 #include <dix-config.h>
34 /* This file holds the driver allocated pixmaps specific implementation. */
36 static _X_INLINE
void *
37 ExaGetPixmapAddress(PixmapPtr p
)
41 return pExaPixmap
->sys_ptr
;
45 * exaCreatePixmap() creates a new pixmap.
47 * Pixmaps are always marked as pinned, because exa has no control over them.
50 exaCreatePixmap_driver(ScreenPtr pScreen
, int w
, int h
, int depth
,
54 ExaPixmapPrivPtr pExaPixmap
;
56 size_t paddedWidth
, datasize
;
58 ExaScreenPriv(pScreen
);
60 if (w
> 32767 || h
> 32767)
63 swap(pExaScr
, pScreen
, CreatePixmap
);
64 pPixmap
= pScreen
->CreatePixmap(pScreen
, 0, 0, depth
, usage_hint
);
65 swap(pExaScr
, pScreen
, CreatePixmap
);
70 pExaPixmap
= ExaGetPixmapPriv(pPixmap
);
71 pExaPixmap
->driverPriv
= NULL
;
73 bpp
= pPixmap
->drawable
.bitsPerPixel
;
75 /* Set this before driver hooks, to allow for driver pixmaps without gpu
76 * memory to back it. These pixmaps have a valid pointer at all times.
78 pPixmap
->devPrivate
.ptr
= NULL
;
80 if (pExaScr
->info
->CreatePixmap2
) {
83 pExaPixmap
->driverPriv
=
84 pExaScr
->info
->CreatePixmap2(pScreen
, w
, h
, depth
, usage_hint
, bpp
,
86 paddedWidth
= pExaPixmap
->fb_pitch
= new_pitch
;
89 paddedWidth
= ((w
* bpp
+ FB_MASK
) >> FB_SHIFT
) * sizeof(FbBits
);
90 if (paddedWidth
/ 4 > 32767 || h
> 32767)
93 exaSetFbPitch(pExaScr
, pExaPixmap
, w
, h
, bpp
);
95 if (paddedWidth
< pExaPixmap
->fb_pitch
)
96 paddedWidth
= pExaPixmap
->fb_pitch
;
97 datasize
= h
* paddedWidth
;
98 pExaPixmap
->driverPriv
=
99 pExaScr
->info
->CreatePixmap(pScreen
, datasize
, 0);
102 if (!pExaPixmap
->driverPriv
) {
103 swap(pExaScr
, pScreen
, DestroyPixmap
);
104 pScreen
->DestroyPixmap(pPixmap
);
105 swap(pExaScr
, pScreen
, DestroyPixmap
);
109 /* Allow ModifyPixmapHeader to set sys_ptr appropriately. */
110 pExaPixmap
->score
= EXA_PIXMAP_SCORE_PINNED
;
111 pExaPixmap
->fb_ptr
= NULL
;
112 pExaPixmap
->pDamage
= NULL
;
113 pExaPixmap
->sys_ptr
= NULL
;
115 (*pScreen
->ModifyPixmapHeader
) (pPixmap
, w
, h
, 0, 0, paddedWidth
, NULL
);
117 pExaPixmap
->area
= NULL
;
119 exaSetAccelBlock(pExaScr
, pExaPixmap
, w
, h
, bpp
);
121 pExaPixmap
->use_gpu_copy
= exaPixmapHasGpuCopy(pPixmap
);
123 /* During a fallback we must prepare access. */
124 if (pExaScr
->fallback_counter
)
125 exaPrepareAccess(&pPixmap
->drawable
, EXA_PREPARE_AUX_DEST
);
131 exaModifyPixmapHeader_driver(PixmapPtr pPixmap
, int width
, int height
,
132 int depth
, int bitsPerPixel
, int devKind
,
136 ExaScreenPrivPtr pExaScr
;
137 ExaPixmapPrivPtr pExaPixmap
;
143 pScreen
= pPixmap
->drawable
.pScreen
;
144 pExaScr
= ExaGetScreenPriv(pScreen
);
145 pExaPixmap
= ExaGetPixmapPriv(pPixmap
);
149 pExaPixmap
->sys_ptr
= pPixData
;
152 pExaPixmap
->sys_pitch
= devKind
;
154 if (width
> 0 && height
> 0 && bitsPerPixel
> 0) {
155 exaSetFbPitch(pExaScr
, pExaPixmap
, width
, height
, bitsPerPixel
);
157 exaSetAccelBlock(pExaScr
, pExaPixmap
, width
, height
, bitsPerPixel
);
161 if (pExaScr
->info
->ModifyPixmapHeader
) {
162 ret
= pExaScr
->info
->ModifyPixmapHeader(pPixmap
, width
, height
, depth
,
163 bitsPerPixel
, devKind
,
165 /* For EXA_HANDLES_PIXMAPS, we set pPixData to NULL.
166 * If pPixmap->devPrivate.ptr is non-NULL, then we've got a
167 * !has_gpu_copy pixmap. We need to store the pointer,
168 * because PrepareAccess won't be called.
170 if (!pPixData
&& pPixmap
->devPrivate
.ptr
&& pPixmap
->devKind
) {
171 pExaPixmap
->sys_ptr
= pPixmap
->devPrivate
.ptr
;
172 pExaPixmap
->sys_pitch
= pPixmap
->devKind
;
178 swap(pExaScr
, pScreen
, ModifyPixmapHeader
);
179 ret
= pScreen
->ModifyPixmapHeader(pPixmap
, width
, height
, depth
,
180 bitsPerPixel
, devKind
, pPixData
);
181 swap(pExaScr
, pScreen
, ModifyPixmapHeader
);
184 /* Always NULL this, we don't want lingering pointers. */
185 pPixmap
->devPrivate
.ptr
= NULL
;
191 exaDestroyPixmap_driver(PixmapPtr pPixmap
)
193 ScreenPtr pScreen
= pPixmap
->drawable
.pScreen
;
195 ExaScreenPriv(pScreen
);
198 if (pPixmap
->refcnt
== 1) {
199 ExaPixmapPriv(pPixmap
);
201 exaDestroyPixmap(pPixmap
);
203 if (pExaPixmap
->driverPriv
)
204 pExaScr
->info
->DestroyPixmap(pScreen
, pExaPixmap
->driverPriv
);
205 pExaPixmap
->driverPriv
= NULL
;
208 swap(pExaScr
, pScreen
, DestroyPixmap
);
209 ret
= pScreen
->DestroyPixmap(pPixmap
);
210 swap(pExaScr
, pScreen
, DestroyPixmap
);
216 exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap
)
218 ScreenPtr pScreen
= pPixmap
->drawable
.pScreen
;
220 ExaScreenPriv(pScreen
);
224 saved_ptr
= pPixmap
->devPrivate
.ptr
;
225 pPixmap
->devPrivate
.ptr
= ExaGetPixmapAddress(pPixmap
);
226 ret
= pExaScr
->info
->PixmapIsOffscreen(pPixmap
);
227 pPixmap
->devPrivate
.ptr
= saved_ptr
;