aboutsummaryrefslogtreecommitdiffstats
path: root/common/rfb/PixelFormatBPP.cxx
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2014-01-30 10:47:07 +0100
committerPierre Ossman <ossman@cendio.se>2014-07-09 14:55:30 +0200
commitc02c05d403f000d15f736458b8c26ad60b4811f0 (patch)
tree5716d8ffa9f75209cc1a5051b5d235e0407a5f7b /common/rfb/PixelFormatBPP.cxx
parent761fe24089bfe95028b0da02a12650351b244165 (diff)
downloadtigervnc-c02c05d403f000d15f736458b8c26ad60b4811f0.tar.gz
tigervnc-c02c05d403f000d15f736458b8c26ad60b4811f0.zip
Add optimised buffer conversion
Handles the common cases when the target or source are in the preferred 888 format. If one of the buffers is not 888, then it must also be properly aligned (which is commonly the case). Performance is now in many cases on par with PixelTransformer.
Diffstat (limited to 'common/rfb/PixelFormatBPP.cxx')
-rw-r--r--common/rfb/PixelFormatBPP.cxx155
1 files changed, 155 insertions, 0 deletions
diff --git a/common/rfb/PixelFormatBPP.cxx b/common/rfb/PixelFormatBPP.cxx
new file mode 100644
index 00000000..6b5ad6bb
--- /dev/null
+++ b/common/rfb/PixelFormatBPP.cxx
@@ -0,0 +1,155 @@
+/* Copyright 2014 Pierre Ossman for Cendio AB
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+#define CONCAT2(a,b) a##b
+#define CONCAT2E(a,b) CONCAT2(a,b)
+
+#define UIN CONCAT2E(U,INBPP)
+#define UOUT CONCAT2E(U,OUTBPP)
+
+#define SWAP16(n) ((((n) & 0xff) << 8) | (((n) >> 8) & 0xff))
+#define SWAP32(n) (((n) >> 24) | (((n) & 0x00ff0000) >> 8) | \
+ (((n) & 0x0000ff00) << 8) | ((n) << 24))
+
+#define SWAPIN CONCAT2E(SWAP,INBPP)
+#define SWAPOUT CONCAT2E(SWAP,OUTBPP)
+
+#if INBPP == 32
+
+void PixelFormat::directBufferFromBufferFrom888(rdr::UOUT* dst,
+ const PixelFormat &srcPF,
+ const rdr::U8* src,
+ int w, int h,
+ int dstStride,
+ int srcStride) const
+{
+ const rdr::U8 *r, *g, *b;
+ int dstPad, srcPad;
+
+ int redTruncShift, greenTruncShift, blueTruncShift;
+
+ redTruncShift = 8 - redBits;
+ greenTruncShift = 8 - greenBits;
+ blueTruncShift = 8 - blueBits;
+
+ if (srcPF.bigEndian) {
+ r = src + (24 - srcPF.redShift)/8;
+ g = src + (24 - srcPF.greenShift)/8;
+ b = src + (24 - srcPF.blueShift)/8;
+ } else {
+ r = src + srcPF.redShift/8;
+ g = src + srcPF.greenShift/8;
+ b = src + srcPF.blueShift/8;
+ }
+
+ dstPad = (dstStride - w);
+ srcPad = (srcStride - w) * 4;
+ while (h--) {
+ int w_ = w;
+ while (w_--) {
+ rdr::UOUT d;
+
+ d = (*r >> redTruncShift) << redShift;
+ d |= (*g >> greenTruncShift) << greenShift;
+ d |= (*b >> blueTruncShift) << blueShift;
+
+#if OUTBPP != 8
+ if (endianMismatch)
+ d = SWAPOUT(d);
+#endif
+
+ *dst = d;
+
+ dst++;
+ r += 4;
+ g += 4;
+ b += 4;
+ }
+ dst += dstPad;
+ r += srcPad;
+ g += srcPad;
+ b += srcPad;
+ }
+}
+
+#endif /* INBPP == 32 */
+
+#if OUTBPP == 32
+
+void PixelFormat::directBufferFromBufferTo888(rdr::U8* dst,
+ const PixelFormat &srcPF,
+ const rdr::UIN* src,
+ int w, int h,
+ int dstStride,
+ int srcStride) const
+{
+ rdr::U8 *r, *g, *b, *x;
+ int dstPad, srcPad;
+
+ const rdr::U8 *redUpTable, *greenUpTable, *blueUpTable;
+
+ redUpTable = &upconvTable[(srcPF.redBits-1)*256];
+ greenUpTable = &upconvTable[(srcPF.greenBits-1)*256];
+ blueUpTable = &upconvTable[(srcPF.blueBits-1)*256];
+
+ if (bigEndian) {
+ r = dst + (24 - redShift)/8;
+ g = dst + (24 - greenShift)/8;
+ b = dst + (24 - blueShift)/8;
+ x = dst + (24 - (48 - redShift - greenShift - blueShift))/8;
+ } else {
+ r = dst + redShift/8;
+ g = dst + greenShift/8;
+ b = dst + blueShift/8;
+ x = dst + (48 - redShift - greenShift - blueShift)/8;
+ }
+
+ dstPad = (dstStride - w) * 4;
+ srcPad = (srcStride - w);
+ while (h--) {
+ int w_ = w;
+ while (w_--) {
+ rdr::UIN s;
+
+ s = *src;
+
+#if INBPP != 8
+ if (srcPF.endianMismatch)
+ s = SWAPIN(s);
+#endif
+
+ *r = redUpTable[(s >> srcPF.redShift) & 0xff];
+ *g = greenUpTable[(s >> srcPF.greenShift) & 0xff];
+ *b = blueUpTable[(s >> srcPF.blueShift) & 0xff];
+ *x = 0;
+
+ r += 4;
+ g += 4;
+ b += 4;
+ x += 4;
+ src++;
+ }
+ r += dstPad;
+ g += dstPad;
+ b += dstPad;
+ x += dstPad;
+ src += srcPad;
+ }
+}
+
+#endif /* OUTBPP == 32 */