3 Copyright 1993, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of The Open Group shall
23 not be used in advertising or otherwise to promote the sale, use or
24 other dealings in this Software without prior written authorization
29 #ifdef HAVE_DIX_CONFIG_H
30 #include <dix-config.h>
34 #include "scrnintstr.h"
37 #include "windowstr.h"
39 #include "dixstruct.h"
45 * Scratch pixmap management and device independent pixmap allocation
51 GetScratchPixmapHeader(ScreenPtr pScreen
, int width
, int height
, int depth
,
52 int bitsPerPixel
, int devKind
, pointer pPixData
)
54 PixmapPtr pPixmap
= pScreen
->pScratchPixmap
;
57 pScreen
->pScratchPixmap
= NULL
;
59 /* width and height of 0 means don't allocate any pixmap data */
60 pPixmap
= (*pScreen
->CreatePixmap
) (pScreen
, 0, 0, depth
, 0);
63 if ((*pScreen
->ModifyPixmapHeader
) (pPixmap
, width
, height
, depth
,
64 bitsPerPixel
, devKind
, pPixData
))
66 (*pScreen
->DestroyPixmap
) (pPixmap
);
73 FreeScratchPixmapHeader(PixmapPtr pPixmap
)
76 ScreenPtr pScreen
= pPixmap
->drawable
.pScreen
;
78 pPixmap
->devPrivate
.ptr
= NULL
; /* lest ddx chases bad ptr */
79 if (pScreen
->pScratchPixmap
)
80 (*pScreen
->DestroyPixmap
) (pPixmap
);
82 pScreen
->pScratchPixmap
= pPixmap
;
87 CreateScratchPixmapsForScreen(ScreenPtr pScreen
)
89 unsigned int pixmap_size
;
91 pixmap_size
= sizeof(PixmapRec
) + dixScreenSpecificPrivatesSize(pScreen
, PRIVATE_PIXMAP
);
92 pScreen
->totalPixmapSize
=
93 BitmapBytePad(pixmap_size
* 8);
95 /* let it be created on first use */
96 pScreen
->pScratchPixmap
= NULL
;
101 FreeScratchPixmapsForScreen(ScreenPtr pScreen
)
103 FreeScratchPixmapHeader(pScreen
->pScratchPixmap
);
106 /* callable by ddx */
108 AllocatePixmap(ScreenPtr pScreen
, int pixDataSize
)
112 assert(pScreen
->totalPixmapSize
> 0);
114 if (pScreen
->totalPixmapSize
> ((size_t) - 1) - pixDataSize
)
117 pPixmap
= malloc(pScreen
->totalPixmapSize
+ pixDataSize
);
121 dixInitScreenPrivates(pScreen
, pPixmap
, pPixmap
+ 1, PRIVATE_PIXMAP
);
125 /* callable by ddx */
127 FreePixmap(PixmapPtr pPixmap
)
129 dixFiniPrivates(pPixmap
, PRIVATE_PIXMAP
);
133 PixmapPtr
PixmapShareToSlave(PixmapPtr pixmap
, ScreenPtr slave
)
138 ScreenPtr master
= pixmap
->drawable
.pScreen
;
139 int depth
= pixmap
->drawable
.depth
;
141 ret
= master
->SharePixmapBacking(pixmap
, slave
, &handle
);
145 spix
= slave
->CreatePixmap(slave
, 0, 0, depth
,
146 CREATE_PIXMAP_USAGE_SHARED
);
147 slave
->ModifyPixmapHeader(spix
, pixmap
->drawable
.width
,
148 pixmap
->drawable
.height
, depth
, 0,
149 pixmap
->devKind
, NULL
);
151 /* have the slave pixmap take a reference on the master pixmap
152 later we destroy them both at the same time */
155 spix
->master_pixmap
= pixmap
;
157 ret
= slave
->SetSharedPixmapBacking(spix
, handle
);
159 slave
->DestroyPixmap(spix
);
167 PixmapStartDirtyTracking(PixmapPtr src
,
171 ScreenPtr screen
= src
->drawable
.pScreen
;
172 PixmapDirtyUpdatePtr dirty_update
;
174 dirty_update
= calloc(1, sizeof(PixmapDirtyUpdateRec
));
178 dirty_update
->src
= src
;
179 dirty_update
->slave_dst
= slave_dst
;
183 dirty_update
->damage
= DamageCreate(NULL
, NULL
,
185 TRUE
, src
->drawable
.pScreen
,
186 src
->drawable
.pScreen
);
187 if (!dirty_update
->damage
) {
192 DamageRegister(&src
->drawable
, dirty_update
->damage
);
193 xorg_list_add(&dirty_update
->ent
, &screen
->pixmap_dirty_list
);
198 PixmapStopDirtyTracking(PixmapPtr src
, PixmapPtr slave_dst
)
200 ScreenPtr screen
= src
->drawable
.pScreen
;
201 PixmapDirtyUpdatePtr ent
, safe
;
203 xorg_list_for_each_entry_safe(ent
, safe
, &screen
->pixmap_dirty_list
, ent
) {
204 if (ent
->src
== src
&& ent
->slave_dst
== slave_dst
) {
205 DamageDestroy(ent
->damage
);
206 xorg_list_del(&ent
->ent
);
214 * this function can possibly be improved and optimised, by clipping
215 * instead of iterating
217 Bool
PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty
, RegionPtr dirty_region
)
219 ScreenPtr pScreen
= dirty
->src
->drawable
.pScreen
;
222 RegionPtr region
= DamageRegion(dirty
->damage
);
225 SourceValidateProcPtr SourceValidate
;
228 * SourceValidate is used by the software cursor code
229 * to pull the cursor off of the screen when reading
230 * bits from the frame buffer. Bypassing this function
231 * leaves the software cursor in place
233 SourceValidate
= pScreen
->SourceValidate
;
234 pScreen
->SourceValidate
= NULL
;
236 RegionTranslate(dirty_region
, dirty
->x
, dirty
->y
);
237 RegionIntersect(dirty_region
, dirty_region
, region
);
239 if (RegionNil(dirty_region
)) {
240 RegionUninit(dirty_region
);
244 dst
= dirty
->slave_dst
->master_pixmap
;
246 dst
= dirty
->slave_dst
;
248 RegionTranslate(dirty_region
, -dirty
->x
, -dirty
->y
);
249 n
= RegionNumRects(dirty_region
);
250 b
= RegionRects(dirty_region
);
252 pGC
= GetScratchGC(dirty
->src
->drawable
.depth
, pScreen
);
253 ValidateGC(&dst
->drawable
, pGC
);
260 w
= dst_box
.x2
- dst_box
.x1
;
261 h
= dst_box
.y2
- dst_box
.y1
;
263 pGC
->ops
->CopyArea(&dirty
->src
->drawable
, &dst
->drawable
, pGC
,
264 dirty
->x
+ dst_box
.x1
, dirty
->y
+ dst_box
.y1
, w
, h
, dst_box
.x1
, dst_box
.y1
);
269 pScreen
->SourceValidate
= SourceValidate
;