]> source.dussan.org Git - tigervnc.git/commitdiff
Hook remaining XRender operations
authorPierre Ossman <ossman@cendio.se>
Tue, 23 Jan 2018 10:55:18 +0000 (11:55 +0100)
committerPierre Ossman <ossman@cendio.se>
Tue, 23 Jan 2018 10:55:18 +0000 (11:55 +0100)
We had overlooked a few so we didn't track all screen changes properly.

unix/xserver/hw/vnc/vncHooks.c

index 5b90f5311f6d57e47112fe95970c2e8edfb5a5eb..38dac928d90d47804b1f8668182b95b8ffb8ba6d 100644 (file)
@@ -71,6 +71,11 @@ typedef struct _vncHooksScreenRec {
 #ifdef RENDER
   CompositeProcPtr             Composite;
   GlyphsProcPtr                Glyphs;
+  CompositeRectsProcPtr        CompositeRects;
+  TrapezoidsProcPtr            Trapezoids;
+  TrianglesProcPtr             Triangles;
+  TriStripProcPtr              TriStrip;
+  TriFanProcPtr                TriFan;
 #endif
 #ifdef RANDR
   RRSetConfigProcPtr           rrSetConfig;
@@ -150,6 +155,20 @@ static void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
 static void vncHooksGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, 
                              PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlists, 
                              GlyphListPtr lists, GlyphPtr * glyphs);
+static void vncHooksCompositeRects(CARD8 op, PicturePtr pDst,
+            xRenderColor * color, int nRect, xRectangle *rects);
+static void vncHooksTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+            PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+            int ntrap, xTrapezoid * traps);
+static void vncHooksTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+            PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+            int ntri, xTriangle * tris);
+static void vncHooksTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+            PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+            int npoint, xPointFixed * points);
+static void vncHooksTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+            PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+            int npoint, xPointFixed * points);
 #endif
 #ifdef RANDR
 static Bool vncHooksRandRSetConfig(ScreenPtr pScreen, Rotation rotation,
@@ -307,6 +326,11 @@ int vncHooksInit(int scrIdx)
   if (ps) {
     wrap(vncHooksScreen, ps, Composite, vncHooksComposite);
     wrap(vncHooksScreen, ps, Glyphs, vncHooksGlyphs);
+    wrap(vncHooksScreen, ps, CompositeRects, vncHooksCompositeRects);
+    wrap(vncHooksScreen, ps, Trapezoids, vncHooksTrapezoids);
+    wrap(vncHooksScreen, ps, Triangles, vncHooksTriangles);
+    wrap(vncHooksScreen, ps, TriStrip, vncHooksTriStrip);
+    wrap(vncHooksScreen, ps, TriFan, vncHooksTriFan);
   }
 #endif
 #ifdef RANDR
@@ -462,6 +486,11 @@ static Bool vncHooksCloseScreen(ScreenPtr pScreen_)
   if (ps) {
     unwrap(vncHooksScreen, ps, Composite);
     unwrap(vncHooksScreen, ps, Glyphs);
+    unwrap(vncHooksScreen, ps, CompositeRects);
+    unwrap(vncHooksScreen, ps, Trapezoids);
+    unwrap(vncHooksScreen, ps, Triangles);
+    unwrap(vncHooksScreen, ps, TriStrip);
+    unwrap(vncHooksScreen, ps, TriFan);
   }
 #endif
 #ifdef RANDR
@@ -881,6 +910,281 @@ static void vncHooksGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
   RENDER_EPILOGUE(Glyphs);
 }
 
+static void vncHooksCompositeRects(CARD8 op, PicturePtr pDst,
+            xRenderColor * color, int nRect, xRectangle *rects)
+{
+  RegionPtr changed;
+
+  RENDER_PROLOGUE(pDst->pDrawable->pScreen, CompositeRects);
+
+  if (is_visible(pDst->pDrawable)) {
+    changed = RECTS_TO_REGION(pScreen, nRect, rects, CT_NONE);
+  } else {
+    changed = REGION_CREATE(pScreen, NullBox, 0);
+  }
+
+  (*ps->CompositeRects)(op, pDst, color, nRect, rects);
+
+  if (REGION_NOTEMPTY(pScreen, changed))
+    add_changed(pScreen, changed);
+
+  REGION_DESTROY(pScreen, changed);
+
+  RENDER_EPILOGUE(CompositeRects);
+}
+
+static inline short FixedToShort(xFixed fixed)
+{
+  return (fixed + 0x8000) >> 16;
+}
+
+static void vncHooksTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+            PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+            int ntrap, xTrapezoid * traps)
+{
+  RegionRec changed;
+
+  RENDER_PROLOGUE(pDst->pDrawable->pScreen, Trapezoids);
+
+  if (is_visible(pDst->pDrawable)) {
+    BoxRec box;
+    RegionRec fbreg;
+
+    // FIXME: We do a very crude bounding box around everything.
+    //        Might not be worth optimizing since this call is rarely
+    //        used.
+    box.x1 = SHRT_MAX;
+    box.y1 = SHRT_MAX;
+    box.x2 = 0;
+    box.y2 = 0;
+    for (int i = 0;i < ntrap;i++) {
+      if (FixedToShort(traps[i].left.p1.x) < box.x1)
+        box.x1 = FixedToShort(traps[i].left.p1.x);
+      if (FixedToShort(traps[i].left.p2.x) < box.x1)
+        box.x1 = FixedToShort(traps[i].left.p2.x);
+      if (FixedToShort(traps[i].top) < box.y1)
+        box.y1 = FixedToShort(traps[i].top);
+      if (FixedToShort(traps[i].right.p1.x) > box.x2)
+        box.x2 = FixedToShort(traps[i].right.p1.x);
+      if (FixedToShort(traps[i].right.p2.x) > box.x2)
+        box.x2 = FixedToShort(traps[i].right.p2.x);
+      if (FixedToShort(traps[i].bottom) > box.y2)
+        box.y2 = FixedToShort(traps[i].bottom);
+    }
+
+    box.x1 += pDst->pDrawable->x;
+    box.y1 += pDst->pDrawable->y;
+    box.x2 += pDst->pDrawable->x;
+    box.y2 += pDst->pDrawable->y;
+    REGION_INIT(pScreen, &changed, &box, 0);
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = pScreen->width;
+    box.y2 = pScreen->height;
+    REGION_INIT(pScreen, &fbreg, &box, 0);
+
+    REGION_INTERSECT(pScreen, &changed, &changed, &fbreg);
+
+    REGION_UNINIT(pScreen, &fbreg);
+  } else {
+    REGION_NULL(pScreen, &changed);
+  }
+
+  (*ps->Trapezoids)(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
+
+  if (REGION_NOTEMPTY(pScreen, &changed))
+    add_changed(pScreen, &changed);
+
+  REGION_UNINIT(pScreen, &changed);
+
+  RENDER_EPILOGUE(Trapezoids);
+}
+
+static void vncHooksTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+            PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+            int ntri, xTriangle * tris)
+{
+  RegionRec changed;
+
+  RENDER_PROLOGUE(pDst->pDrawable->pScreen, Triangles);
+
+  if (is_visible(pDst->pDrawable)) {
+    BoxRec box;
+    RegionRec fbreg;
+
+    // FIXME: We do a very crude bounding box around everything.
+    //        Might not be worth optimizing since this call is rarely
+    //        used.
+    box.x1 = SHRT_MAX;
+    box.y1 = SHRT_MAX;
+    box.x2 = 0;
+    box.y2 = 0;
+    for (int i = 0;i < ntri;i++) {
+      xFixed left, right, top, bottom;
+
+      left = min(min(tris[i].p1.x, tris[i].p2.x), tris[i].p3.x);
+      right = max(max(tris[i].p1.x, tris[i].p2.x), tris[i].p3.x);
+      top = min(min(tris[i].p1.y, tris[i].p2.y), tris[i].p3.y);
+      bottom = max(max(tris[i].p1.y, tris[i].p2.y), tris[i].p3.y);
+
+      if (FixedToShort(left) < box.x1)
+        box.x1 = FixedToShort(left);
+      if (FixedToShort(top) < box.y1)
+        box.y1 = FixedToShort(top);
+      if (FixedToShort(right) > box.x2)
+        box.x2 = FixedToShort(right);
+      if (FixedToShort(bottom) > box.y2)
+        box.y2 = FixedToShort(bottom);
+    }
+
+    box.x1 += pDst->pDrawable->x;
+    box.y1 += pDst->pDrawable->y;
+    box.x2 += pDst->pDrawable->x;
+    box.y2 += pDst->pDrawable->y;
+    REGION_INIT(pScreen, &changed, &box, 0);
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = pScreen->width;
+    box.y2 = pScreen->height;
+    REGION_INIT(pScreen, &fbreg, &box, 0);
+
+    REGION_INTERSECT(pScreen, &changed, &changed, &fbreg);
+
+    REGION_UNINIT(pScreen, &fbreg);
+  } else {
+    REGION_NULL(pScreen, &changed);
+  }
+
+  (*ps->Triangles)(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
+
+  if (REGION_NOTEMPTY(pScreen, &changed))
+    add_changed(pScreen, &changed);
+
+  REGION_UNINIT(pScreen, &changed);
+
+  RENDER_EPILOGUE(Triangles);
+}
+
+static void vncHooksTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+            PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+            int npoint, xPointFixed * points)
+{
+  RegionRec changed;
+
+  RENDER_PROLOGUE(pDst->pDrawable->pScreen, TriStrip);
+
+  if (is_visible(pDst->pDrawable)) {
+    BoxRec box;
+    RegionRec fbreg;
+
+    // FIXME: We do a very crude bounding box around everything.
+    //        Might not be worth optimizing since this call is rarely
+    //        used.
+    box.x1 = SHRT_MAX;
+    box.y1 = SHRT_MAX;
+    box.x2 = 0;
+    box.y2 = 0;
+    for (int i = 0;i < npoint;i++) {
+      if (FixedToShort(points[i].x) < box.x1)
+        box.x1 = FixedToShort(points[i].x);
+      if (FixedToShort(points[i].y) < box.y1)
+        box.y1 = FixedToShort(points[i].y);
+      if (FixedToShort(points[i].x) > box.x2)
+        box.x2 = FixedToShort(points[i].x);
+      if (FixedToShort(points[i].y) > box.y2)
+        box.y2 = FixedToShort(points[i].y);
+    }
+
+    box.x1 += pDst->pDrawable->x;
+    box.y1 += pDst->pDrawable->y;
+    box.x2 += pDst->pDrawable->x;
+    box.y2 += pDst->pDrawable->y;
+    REGION_INIT(pScreen, &changed, &box, 0);
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = pScreen->width;
+    box.y2 = pScreen->height;
+    REGION_INIT(pScreen, &fbreg, &box, 0);
+
+    REGION_INTERSECT(pScreen, &changed, &changed, &fbreg);
+
+    REGION_UNINIT(pScreen, &fbreg);
+  } else {
+    REGION_NULL(pScreen, &changed);
+  }
+
+  (*ps->TriStrip)(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, points);
+
+  if (REGION_NOTEMPTY(pScreen, &changed))
+    add_changed(pScreen, &changed);
+
+  REGION_UNINIT(pScreen, &changed);
+
+  RENDER_EPILOGUE(TriStrip);
+}
+
+static void vncHooksTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+            PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+            int npoint, xPointFixed * points)
+{
+  RegionRec changed;
+
+  RENDER_PROLOGUE(pDst->pDrawable->pScreen, TriFan);
+
+  if (is_visible(pDst->pDrawable)) {
+    BoxRec box;
+    RegionRec fbreg;
+
+    // FIXME: We do a very crude bounding box around everything.
+    //        Might not be worth optimizing since this call is rarely
+    //        used.
+    box.x1 = SHRT_MAX;
+    box.y1 = SHRT_MAX;
+    box.x2 = 0;
+    box.y2 = 0;
+    for (int i = 0;i < npoint;i++) {
+      if (FixedToShort(points[i].x) < box.x1)
+        box.x1 = FixedToShort(points[i].x);
+      if (FixedToShort(points[i].y) < box.y1)
+        box.y1 = FixedToShort(points[i].y);
+      if (FixedToShort(points[i].x) > box.x2)
+        box.x2 = FixedToShort(points[i].x);
+      if (FixedToShort(points[i].y) > box.y2)
+        box.y2 = FixedToShort(points[i].y);
+    }
+
+    box.x1 += pDst->pDrawable->x;
+    box.y1 += pDst->pDrawable->y;
+    box.x2 += pDst->pDrawable->x;
+    box.y2 += pDst->pDrawable->y;
+    REGION_INIT(pScreen, &changed, &box, 0);
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = pScreen->width;
+    box.y2 = pScreen->height;
+    REGION_INIT(pScreen, &fbreg, &box, 0);
+
+    REGION_INTERSECT(pScreen, &changed, &changed, &fbreg);
+
+    REGION_UNINIT(pScreen, &fbreg);
+  } else {
+    REGION_NULL(pScreen, &changed);
+  }
+
+  (*ps->TriFan)(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, points);
+
+  if (REGION_NOTEMPTY(pScreen, &changed))
+    add_changed(pScreen, &changed);
+
+  REGION_UNINIT(pScreen, &changed);
+
+  RENDER_EPILOGUE(TriFan);
+}
+
 #endif /* RENDER */
 
 #ifdef RANDR