mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-04-01 02:20:43 +02:00
Merge branch 'server-21.1-branch' into 'server-21.1-branch'
rootless: Fix Glyphs damage bounding box to correctly compute union See merge request xorg/xserver!2154
This commit is contained in:
commit
ff1347c18f
2 changed files with 176 additions and 3 deletions
|
|
@ -108,6 +108,9 @@ typedef struct _RootlessScreenRec {
|
|||
|
||||
CompositeProcPtr Composite;
|
||||
GlyphsProcPtr Glyphs;
|
||||
TrapezoidsProcPtr Trapezoids;
|
||||
TrianglesProcPtr Triangles;
|
||||
CompositeRectsProcPtr CompositeRects;
|
||||
|
||||
InstallColormapProcPtr InstallColormap;
|
||||
UninstallColormapProcPtr UninstallColormap;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include "propertyst.h"
|
||||
#include "mivalidate.h"
|
||||
#include "picturestr.h"
|
||||
#include "mipict.h"
|
||||
#include "colormapst.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
|
@ -51,6 +52,30 @@
|
|||
#include "rootlessCommon.h"
|
||||
#include "rootlessWindow.h"
|
||||
|
||||
/*
|
||||
* Render operations use PictFormat to describe pixel layout. Depth-24
|
||||
* windows use PICT_x8r8g8b8, where 'x' tells pixman the high byte is
|
||||
* padding it may freely zero. The compositor needs this byte to be 0xFF
|
||||
* (opaque). Temporarily upgrading the destination format from 'x' to 'a'
|
||||
* prevents pixman from optimizing away the alpha channel, paralleling how
|
||||
* ROOTLESS_PROTECT_ALPHA prevents fb from doing the same for GC ops.
|
||||
*/
|
||||
|
||||
#if ROOTLESS_PROTECT_ALPHA
|
||||
#define RL_RENDER_SAVE_FORMAT(pict) \
|
||||
CARD32 _saved_format = (pict)->format; \
|
||||
if ((pict)->pDrawable->type == DRAWABLE_WINDOW && \
|
||||
(pict)->format == PICT_x8r8g8b8) \
|
||||
(pict)->format = PICT_a8r8g8b8
|
||||
|
||||
#define RL_RENDER_RESTORE_FORMAT(pict) \
|
||||
(pict)->format = _saved_format
|
||||
|
||||
#else
|
||||
#define RL_RENDER_SAVE_FORMAT(pict)
|
||||
#define RL_RENDER_RESTORE_FORMAT(pict)
|
||||
#endif
|
||||
|
||||
extern int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild,
|
||||
VTKind kind);
|
||||
extern Bool RootlessCreateGC(GCPtr pGC);
|
||||
|
|
@ -257,8 +282,10 @@ RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
|
|||
if (dstWin && IsFramedWindow(dstWin))
|
||||
RootlessStartDrawing(dstWin);
|
||||
|
||||
RL_RENDER_SAVE_FORMAT(pDst);
|
||||
ps->Composite(op, pSrc, pMask, pDst,
|
||||
xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
|
||||
RL_RENDER_RESTORE_FORMAT(pDst);
|
||||
|
||||
if (dstWin && IsFramedWindow(dstWin)) {
|
||||
RootlessDamageRect(dstWin, xDst, yDst, width, height);
|
||||
|
|
@ -292,7 +319,9 @@ RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
|||
|
||||
//SCREEN_UNWRAP(ps, Glyphs);
|
||||
ps->Glyphs = SCREENREC(pScreen)->Glyphs;
|
||||
RL_RENDER_SAVE_FORMAT(pDst);
|
||||
ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
|
||||
RL_RENDER_RESTORE_FORMAT(pDst);
|
||||
ps->Glyphs = RootlessGlyphs;
|
||||
//SCREEN_WRAP(ps, Glyphs);
|
||||
|
||||
|
|
@ -332,8 +361,8 @@ RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
|||
x2 = x1 + glyph->info.width;
|
||||
y2 = y1 + glyph->info.height;
|
||||
|
||||
box.x1 = max(box.x1, x1);
|
||||
box.y1 = max(box.y1, y1);
|
||||
box.x1 = min(box.x1, x1);
|
||||
box.y1 = min(box.y1, y1);
|
||||
box.x2 = max(box.x2, x2);
|
||||
box.y2 = max(box.y2, y2);
|
||||
|
||||
|
|
@ -348,6 +377,141 @@ RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
RootlessTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
||||
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
|
||||
int ntrap, xTrapezoid *traps)
|
||||
{
|
||||
ScreenPtr pScreen = pDst->pDrawable->pScreen;
|
||||
PictureScreenPtr ps = GetPictureScreen(pScreen);
|
||||
WindowPtr srcWin, dstWin;
|
||||
|
||||
srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
|
||||
(WindowPtr) pSrc->pDrawable : NULL;
|
||||
dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
|
||||
(WindowPtr) pDst->pDrawable : NULL;
|
||||
|
||||
ps->Trapezoids = SCREENREC(pScreen)->Trapezoids;
|
||||
|
||||
if (srcWin && IsFramedWindow(srcWin))
|
||||
RootlessStartDrawing(srcWin);
|
||||
if (dstWin && IsFramedWindow(dstWin))
|
||||
RootlessStartDrawing(dstWin);
|
||||
|
||||
RL_RENDER_SAVE_FORMAT(pDst);
|
||||
ps->Trapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
|
||||
RL_RENDER_RESTORE_FORMAT(pDst);
|
||||
|
||||
if (dstWin && IsFramedWindow(dstWin) && ntrap > 0) {
|
||||
BoxRec box;
|
||||
|
||||
miTrapezoidBounds(ntrap, traps, &box);
|
||||
|
||||
if (box.x1 < box.x2 && box.y1 < box.y2) {
|
||||
box.x1 += dstWin->drawable.x;
|
||||
box.y1 += dstWin->drawable.y;
|
||||
box.x2 += dstWin->drawable.x;
|
||||
box.y2 += dstWin->drawable.y;
|
||||
RootlessDamageBox(dstWin, &box);
|
||||
}
|
||||
}
|
||||
|
||||
ps->Trapezoids = RootlessTrapezoids;
|
||||
}
|
||||
|
||||
static void
|
||||
RootlessTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
||||
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
|
||||
int ntri, xTriangle *tris)
|
||||
{
|
||||
ScreenPtr pScreen = pDst->pDrawable->pScreen;
|
||||
PictureScreenPtr ps = GetPictureScreen(pScreen);
|
||||
WindowPtr srcWin, dstWin;
|
||||
|
||||
srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
|
||||
(WindowPtr) pSrc->pDrawable : NULL;
|
||||
dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
|
||||
(WindowPtr) pDst->pDrawable : NULL;
|
||||
|
||||
ps->Triangles = SCREENREC(pScreen)->Triangles;
|
||||
|
||||
if (srcWin && IsFramedWindow(srcWin))
|
||||
RootlessStartDrawing(srcWin);
|
||||
if (dstWin && IsFramedWindow(dstWin))
|
||||
RootlessStartDrawing(dstWin);
|
||||
|
||||
RL_RENDER_SAVE_FORMAT(pDst);
|
||||
ps->Triangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
|
||||
RL_RENDER_RESTORE_FORMAT(pDst);
|
||||
|
||||
if (dstWin && IsFramedWindow(dstWin) && ntri > 0) {
|
||||
BoxRec box;
|
||||
|
||||
miTriangleBounds(ntri, tris, &box);
|
||||
|
||||
if (box.x1 < box.x2 && box.y1 < box.y2) {
|
||||
box.x1 += dstWin->drawable.x;
|
||||
box.y1 += dstWin->drawable.y;
|
||||
box.x2 += dstWin->drawable.x;
|
||||
box.y2 += dstWin->drawable.y;
|
||||
RootlessDamageBox(dstWin, &box);
|
||||
}
|
||||
}
|
||||
|
||||
ps->Triangles = RootlessTriangles;
|
||||
}
|
||||
|
||||
static void
|
||||
RootlessCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color,
|
||||
int nRect, xRectangle *rects)
|
||||
{
|
||||
ScreenPtr pScreen = pDst->pDrawable->pScreen;
|
||||
PictureScreenPtr ps = GetPictureScreen(pScreen);
|
||||
WindowPtr dstWin;
|
||||
|
||||
dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
|
||||
(WindowPtr) pDst->pDrawable : NULL;
|
||||
|
||||
ps->CompositeRects = SCREENREC(pScreen)->CompositeRects;
|
||||
|
||||
if (dstWin && IsFramedWindow(dstWin))
|
||||
RootlessStartDrawing(dstWin);
|
||||
|
||||
RL_RENDER_SAVE_FORMAT(pDst);
|
||||
ps->CompositeRects(op, pDst, color, nRect, rects);
|
||||
RL_RENDER_RESTORE_FORMAT(pDst);
|
||||
|
||||
if (dstWin && IsFramedWindow(dstWin) && nRect > 0) {
|
||||
int i;
|
||||
BoxRec box;
|
||||
|
||||
box.x1 = rects[0].x;
|
||||
box.y1 = rects[0].y;
|
||||
box.x2 = rects[0].x + rects[0].width;
|
||||
box.y2 = rects[0].y + rects[0].height;
|
||||
|
||||
for (i = 1; i < nRect; i++) {
|
||||
short x1 = rects[i].x;
|
||||
short y1 = rects[i].y;
|
||||
short x2 = x1 + rects[i].width;
|
||||
short y2 = y1 + rects[i].height;
|
||||
|
||||
if (x1 < box.x1) box.x1 = x1;
|
||||
if (y1 < box.y1) box.y1 = y1;
|
||||
if (x2 > box.x2) box.x2 = x2;
|
||||
if (y2 > box.y2) box.y2 = y2;
|
||||
}
|
||||
|
||||
if (box.x1 < box.x2 && box.y1 < box.y2) {
|
||||
RootlessDamageRect(dstWin,
|
||||
box.x1, box.y1,
|
||||
box.x2 - box.x1, box.y2 - box.y1);
|
||||
}
|
||||
}
|
||||
|
||||
ps->CompositeRects = RootlessCompositeRects;
|
||||
}
|
||||
|
||||
/*
|
||||
* RootlessValidateTree
|
||||
* ValidateTree is modified in two ways:
|
||||
|
|
@ -685,13 +849,19 @@ RootlessWrap(ScreenPtr pScreen)
|
|||
WRAP(SetShape);
|
||||
|
||||
{
|
||||
// Composite and Glyphs don't use normal screen wrapping
|
||||
// PictureScreen procs don't use normal screen wrapping
|
||||
PictureScreenPtr ps = GetPictureScreen(pScreen);
|
||||
|
||||
s->Composite = ps->Composite;
|
||||
ps->Composite = RootlessComposite;
|
||||
s->Glyphs = ps->Glyphs;
|
||||
ps->Glyphs = RootlessGlyphs;
|
||||
s->Trapezoids = ps->Trapezoids;
|
||||
ps->Trapezoids = RootlessTrapezoids;
|
||||
s->Triangles = ps->Triangles;
|
||||
ps->Triangles = RootlessTriangles;
|
||||
s->CompositeRects = ps->CompositeRects;
|
||||
ps->CompositeRects = RootlessCompositeRects;
|
||||
}
|
||||
|
||||
// WRAP(ClearToBackground); fixme put this back? useful for shaped wins?
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue