diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2016-11-03 23:05:25 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2016-11-11 11:06:54 +0000 |
commit | d05b11e5f590272b0036cf09cf8721c37db33791 (patch) | |
tree | 8da16be50adaf18936699c8e6653324169569156 | |
parent | 74eebc7a0768659426911541e16973bdf037c157 (diff) |
tdf#103803 change from BGRA to RGBA color arrangement on Windows
BGRA is native color arrangement on Windows however some intel
drivers have problems with large textures if they read from a
BGRA buffer. So with this commit we switch to RGBA color
arrangement. This shouldn't cause much performance differences,
but we need to convert from RGBA to BGRA when printing.
+ fix: wrong GL format for RGBA image buffers
commit: ed42212f53b2e52238346e64dae31a931d6c90a1
Reviewed-on: https://gerrit.libreoffice.org/30544
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
(cherry picked from commit 6b571ae4608ac15256eb7582f442ce69975370f3)
Change-Id: Ic112dc6a6c5d8b70e96041d0de15a03bbbdc406f
Reviewed-on: https://gerrit.libreoffice.org/30763
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Michael Meeks <michael.meeks@collabora.com>
-rw-r--r-- | vcl/opengl/salbmp.cxx | 38 | ||||
-rw-r--r-- | vcl/win/gdi/salgdi2.cxx | 67 |
2 files changed, 63 insertions, 42 deletions
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx index ef081ee9fd4d..f9b800565268 100644 --- a/vcl/opengl/salbmp.cxx +++ b/vcl/opengl/salbmp.cxx @@ -55,27 +55,15 @@ inline bool determineTextureFormat(sal_uInt16 nBits, GLenum& nFormat, GLenum& nT nType = GL_UNSIGNED_BYTE; return true; case 16: -#ifdef _WIN32 - nFormat = GL_BGR; -#else nFormat = GL_RGB; -#endif nType = GL_UNSIGNED_SHORT_5_6_5; return true; case 24: -#ifdef _WIN32 - nFormat = GL_BGR; -#else nFormat = GL_RGB; -#endif nType = GL_UNSIGNED_BYTE; return true; case 32: -#ifdef _WIN32 - nFormat = GL_BGRA; -#else nFormat = GL_RGBA; -#endif nType = GL_UNSIGNED_BYTE; return true; default: @@ -816,16 +804,6 @@ BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( BitmapAccessMode nMode ) break; case 16: { -#ifdef _WIN32 - pBuffer->mnFormat = ScanlineFormat::N16BitTcLsbMask; - ColorMaskElement aRedMask(0x00007c00); - aRedMask.CalcMaskShift(); - ColorMaskElement aGreenMask(0x000003e0); - aGreenMask.CalcMaskShift(); - ColorMaskElement aBlueMask(0x0000001f); - aBlueMask.CalcMaskShift(); - pBuffer->maColorMask = ColorMask(aRedMask, aGreenMask, aBlueMask); -#else pBuffer->mnFormat = ScanlineFormat::N16BitTcMsbMask; ColorMaskElement aRedMask(0x0000f800); aRedMask.CalcMaskShift(); @@ -834,30 +812,15 @@ BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( BitmapAccessMode nMode ) ColorMaskElement aBlueMask(0x0000001f); aBlueMask.CalcMaskShift(); pBuffer->maColorMask = ColorMask(aRedMask, aGreenMask, aBlueMask); -#endif break; } case 24: { -#ifdef _WIN32 - pBuffer->mnFormat = ScanlineFormat::N24BitTcBgr; -#else pBuffer->mnFormat = ScanlineFormat::N24BitTcRgb; -#endif break; } case 32: { -#ifdef _WIN32 - pBuffer->mnFormat = ScanlineFormat::N32BitTcBgra; - ColorMaskElement aRedMask(0x00ff0000); - aRedMask.CalcMaskShift(); - ColorMaskElement aGreenMask(0x0000ff00); - aGreenMask.CalcMaskShift(); - ColorMaskElement aBlueMask(0x000000ff); - aBlueMask.CalcMaskShift(); - pBuffer->maColorMask = ColorMask(aRedMask, aGreenMask, aBlueMask); -#else pBuffer->mnFormat = ScanlineFormat::N32BitTcRgba; ColorMaskElement aRedMask(0xff000000); aRedMask.CalcMaskShift(); @@ -866,7 +829,6 @@ BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( BitmapAccessMode nMode ) ColorMaskElement aBlueMask(0x0000ff00); aBlueMask.CalcMaskShift(); pBuffer->maColorMask = ColorMask(aRedMask, aGreenMask, aBlueMask); -#endif break; } } diff --git a/vcl/win/gdi/salgdi2.cxx b/vcl/win/gdi/salgdi2.cxx index 8514e73c1523..751b8c93de24 100644 --- a/vcl/win/gdi/salgdi2.cxx +++ b/vcl/win/gdi/salgdi2.cxx @@ -73,6 +73,45 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY, namespace { +class ColorScanlineConverter +{ +public: + ScanlineFormat meSourceFormat; + ScanlineFormat meDestinationFormat; + + int mnComponentSize; + int mnComponentExchangeIndex; + + long mnScanlineSize; + + ColorScanlineConverter(ScanlineFormat eSourceFormat, ScanlineFormat eDestinationFormat, int nComponentSize, long nScanlineSize) + : meSourceFormat(eSourceFormat) + , meDestinationFormat(eDestinationFormat) + , mnComponentSize(nComponentSize) + , mnComponentExchangeIndex(0) + , mnScanlineSize(nScanlineSize) + { + if (meSourceFormat == ScanlineFormat::N32BitTcAbgr || + meSourceFormat == ScanlineFormat::N32BitTcArgb) + { + mnComponentExchangeIndex = 1; + } + } + + void convertScanline(sal_uInt8* pSource, sal_uInt8* pDestination) + { + for (int x = 0; x < mnScanlineSize; x += mnComponentSize) + { + for (int i = 0; i < mnComponentSize; ++i) + { + pDestination[x + i] = pSource[x + i]; + } + pDestination[x + mnComponentExchangeIndex + 0] = pSource[x + mnComponentExchangeIndex + 2]; + pDestination[x + mnComponentExchangeIndex + 2] = pSource[x + mnComponentExchangeIndex + 0]; + } + } +}; + void convertToWinSalBitmap(SalBitmap& rSalBitmap, WinSalBitmap& rWinSalBitmap) { BitmapPalette aBitmapPalette; @@ -90,11 +129,31 @@ void convertToWinSalBitmap(SalBitmap& rSalBitmap, WinSalBitmap& rWinSalBitmap) sal_uInt8* pSource(pRead->mpBits); sal_uInt8* pDestination(pWrite->mpBits); - for (long y = 0; y < pRead->mnHeight; y++) + std::unique_ptr<ColorScanlineConverter> pConverter; + + if (pRead->mnFormat == ScanlineFormat::N24BitTcRgb) + pConverter.reset(new ColorScanlineConverter(ScanlineFormat::N24BitTcRgb, ScanlineFormat::N24BitTcBgr, + 3, pRead->mnScanlineSize)); + else if (pRead->mnFormat == ScanlineFormat::N32BitTcRgba) + pConverter.reset(new ColorScanlineConverter(ScanlineFormat::N32BitTcRgba, ScanlineFormat::N32BitTcBgra, + 4, pRead->mnScanlineSize)); + if (pConverter) + { + for (long y = 0; y < pRead->mnHeight; y++) + { + pConverter->convertScanline(pSource, pDestination); + pSource += pRead->mnScanlineSize; + pDestination += pWrite->mnScanlineSize; + } + } + else { - memcpy(pDestination, pSource, pRead->mnScanlineSize); - pSource += pRead->mnScanlineSize; - pDestination += pWrite->mnScanlineSize; + for (long y = 0; y < pRead->mnHeight; y++) + { + memcpy(pDestination, pSource, pRead->mnScanlineSize); + pSource += pRead->mnScanlineSize; + pDestination += pWrite->mnScanlineSize; + } } rWinSalBitmap.ReleaseBuffer(pWrite, BitmapAccessMode::Write); |