Kaydet (Commit) f625f1e1 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl Kaydeden (comit) Caolán McNamara

tdf#94851 can't use OpenGLSalBitmap with WinSalGraphics

Printing is done with the WinSalGraphics and not with
WinOpenGLSalGraphics on Windows even when OpenGL is enabled, but
the SalBitmap is still using the OpenGLSalBitmap which can't be
used with WinSalGraphics. So detect when the implementation of
SalGraphic is "wrong" and convert.

(cherry picked from commit 1cc30679)

also includes commit:
tdf#94851 use BGR color order in Windows

(cherry picked from commit 8a498fad)

and commit:
tdf#94851 check SalBitmap & convert in all drawBitmap methods

(cherry picked from commit 917d59a8)

Change-Id: I67c730514a8a016c828b5cafdf6e70ddeca450ec
Reviewed-on: https://gerrit.libreoffice.org/20659Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarCaolán McNamara <caolanm@redhat.com>
Tested-by: 's avatarCaolán McNamara <caolanm@redhat.com>
üst fabfd88b
...@@ -37,6 +37,44 @@ ...@@ -37,6 +37,44 @@
namespace namespace
{ {
inline bool determineTextureFormat(sal_uInt16 nBits, GLenum& nFormat, GLenum& nType)
{
switch(nBits)
{
case 8:
nFormat = GL_LUMINANCE;
nType = GL_UNSIGNED_BYTE;
return true;
case 16:
#ifdef WNT
nFormat = GL_BGR;
#else
nFormat = GL_RGB;
#endif
nType = GL_UNSIGNED_SHORT_5_6_5;
return true;
case 24:
#ifdef WNT
nFormat = GL_BGR;
#else
nFormat = GL_RGB;
#endif
nType = GL_UNSIGNED_BYTE;
return true;
case 32:
#ifdef WNT
nFormat = GL_BGRA;
#else
nFormat = GL_RGBA;
#endif
nType = GL_UNSIGNED_BYTE;
return true;
default:
break;
}
return false;
}
static bool isValidBitCount( sal_uInt16 nBitCount ) static bool isValidBitCount( sal_uInt16 nBitCount )
{ {
return (nBitCount == 1) || (nBitCount == 4) || (nBitCount == 8) || (nBitCount == 16) || (nBitCount == 24) || (nBitCount == 32); return (nBitCount == 1) || (nBitCount == 4) || (nBitCount == 8) || (nBitCount == 16) || (nBitCount == 24) || (nBitCount == 32);
...@@ -396,18 +434,7 @@ GLuint OpenGLSalBitmap::CreateTexture() ...@@ -396,18 +434,7 @@ GLuint OpenGLSalBitmap::CreateTexture()
// no conversion needed for truecolor // no conversion needed for truecolor
pData = maUserBuffer.get(); pData = maUserBuffer.get();
switch( mnBits ) determineTextureFormat(mnBits, nFormat, nType);
{
case 16: nFormat = GL_RGB;
nType = GL_UNSIGNED_SHORT_5_6_5;
break;
case 24: nFormat = GL_RGB;
nType = GL_UNSIGNED_BYTE;
break;
case 32: nFormat = GL_RGBA;
nType = GL_UNSIGNED_BYTE;
break;
}
} }
else if( mnBits == 8 && maPalette.IsGreyPalette() ) else if( mnBits == 8 && maPalette.IsGreyPalette() )
{ {
...@@ -421,8 +448,8 @@ GLuint OpenGLSalBitmap::CreateTexture() ...@@ -421,8 +448,8 @@ GLuint OpenGLSalBitmap::CreateTexture()
// convert to 32 bits RGBA using palette // convert to 32 bits RGBA using palette
pData = new sal_uInt8[mnBufHeight * mnBufWidth * 4]; pData = new sal_uInt8[mnBufHeight * mnBufWidth * 4];
bAllocated = true; bAllocated = true;
nFormat = GL_RGBA;
nType = GL_UNSIGNED_BYTE; determineTextureFormat(32, nFormat, nType);
ImplPixelFormat* pSrcFormat = ImplPixelFormat::GetFormat( mnBits, maPalette ); ImplPixelFormat* pSrcFormat = ImplPixelFormat::GetFormat( mnBits, maPalette );
sal_uInt8* pSrcData = maUserBuffer.get(); sal_uInt8* pSrcData = maUserBuffer.get();
...@@ -469,31 +496,18 @@ bool OpenGLSalBitmap::ReadTexture() ...@@ -469,31 +496,18 @@ bool OpenGLSalBitmap::ReadTexture()
{ {
sal_uInt8* pData = maUserBuffer.get(); sal_uInt8* pData = maUserBuffer.get();
SAL_INFO( "vcl.opengl", "::ReadTexture " << mnWidth << "x" << mnHeight ); SAL_INFO( "vcl.opengl", "::ReadTexture " << mnWidth << "x" << mnHeight );
GLenum nFormat = GL_RGBA;
GLenum nType = GL_UNSIGNED_BYTE;
if( pData == NULL ) if( pData == NULL )
return false; return false;
if (mnBits == 8 || mnBits == 16 || mnBits == 24 || mnBits == 32) if (mnBits == 8 || mnBits == 16 || mnBits == 24 || mnBits == 32)
{ {
GLenum nFormat = GL_RGBA; determineTextureFormat(mnBits, nFormat, nType);
GLenum nType = GL_UNSIGNED_BYTE;
switch( mnBits )
{
case 8: nFormat = GL_LUMINANCE;
nType = GL_UNSIGNED_BYTE;
break;
case 16: nFormat = GL_RGB;
nType = GL_UNSIGNED_SHORT_5_6_5;
break;
case 24: nFormat = GL_RGB;
nType = GL_UNSIGNED_BYTE;
break;
case 32: nFormat = GL_RGBA;
nType = GL_UNSIGNED_BYTE;
break;
}
makeCurrent(); makeCurrent();
maTexture.Read(nFormat, nType, pData); maTexture.Read(nFormat, nType, pData);
...@@ -506,7 +520,8 @@ bool OpenGLSalBitmap::ReadTexture() ...@@ -506,7 +520,8 @@ bool OpenGLSalBitmap::ReadTexture()
std::vector<sal_uInt8> aBuffer(mnWidth * mnHeight * 3); std::vector<sal_uInt8> aBuffer(mnWidth * mnHeight * 3);
makeCurrent(); makeCurrent();
sal_uInt8* pBuffer = aBuffer.data(); sal_uInt8* pBuffer = aBuffer.data();
maTexture.Read(GL_RGB, GL_UNSIGNED_BYTE, pBuffer); determineTextureFormat(24, nFormat, nType);
maTexture.Read(nFormat, nType, pBuffer);
int nShift = 7; int nShift = 7;
size_t nIndex = 0; size_t nIndex = 0;
...@@ -719,12 +734,30 @@ BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( BitmapAccessMode nMode ) ...@@ -719,12 +734,30 @@ BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( BitmapAccessMode nMode )
case 1: pBuffer->mnFormat = BMP_FORMAT_1BIT_MSB_PAL; break; case 1: pBuffer->mnFormat = BMP_FORMAT_1BIT_MSB_PAL; break;
case 4: pBuffer->mnFormat = BMP_FORMAT_4BIT_MSN_PAL; break; case 4: pBuffer->mnFormat = BMP_FORMAT_4BIT_MSN_PAL; break;
case 8: pBuffer->mnFormat = BMP_FORMAT_8BIT_PAL; break; case 8: pBuffer->mnFormat = BMP_FORMAT_8BIT_PAL; break;
case 16: pBuffer->mnFormat = BMP_FORMAT_16BIT_TC_MSB_MASK; case 16:
pBuffer->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f ); #ifdef WNT
pBuffer->mnFormat = BMP_FORMAT_16BIT_TC_MSB_MASK;
pBuffer->maColorMask = ColorMask(0x7c00, 0x03e0, 0x001f);
#else
pBuffer->mnFormat = BMP_FORMAT_16BIT_TC_MSB_MASK;
pBuffer->maColorMask = ColorMask(0xf800, 0x07e0, 0x001f);
#endif
break;
case 24:
#ifdef WNT
pBuffer->mnFormat = BMP_FORMAT_24BIT_TC_BGR;
#else
pBuffer->mnFormat = BMP_FORMAT_24BIT_TC_RGB;
#endif
break; break;
case 24: pBuffer->mnFormat = BMP_FORMAT_24BIT_TC_RGB; break; case 32:
case 32: pBuffer->mnFormat = BMP_FORMAT_32BIT_TC_RGBA; #ifdef WNT
pBuffer->maColorMask = ColorMask( 0xff000000, 0x00ff0000, 0x0000ff00 ); pBuffer->mnFormat = BMP_FORMAT_32BIT_TC_BGRA;
pBuffer->maColorMask = ColorMask(0x00ff0000, 0x0000ff00, 0x000000ff);
#else
pBuffer->mnFormat = BMP_FORMAT_32BIT_TC_RGBA;
pBuffer->maColorMask = ColorMask(0xff000000, 0x00ff0000, 0x0000ff00);
#endif
break; break;
} }
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include "vcl/bmpacc.hxx" #include "vcl/bmpacc.hxx"
#include "outdata.hxx" #include "outdata.hxx"
#include "salgdiimpl.hxx" #include "salgdiimpl.hxx"
#include "opengl/win/gdiimpl.hxx"
bool WinSalGraphics::supportsOperation( OutDevSupportType eType ) const bool WinSalGraphics::supportsOperation( OutDevSupportType eType ) const
{ {
...@@ -69,23 +71,87 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY, ...@@ -69,23 +71,87 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY,
nSrcWidth, nSrcHeight, nFlags ); nSrcWidth, nSrcHeight, nFlags );
} }
namespace
{
void convertToWinSalBitmap(SalBitmap& rSalBitmap, WinSalBitmap& rWinSalBitmap)
{
BitmapBuffer* pRead = rSalBitmap.AcquireBuffer(BITMAP_READ_ACCESS);
rWinSalBitmap.Create(rSalBitmap.GetSize(), rSalBitmap.GetBitCount(), BitmapPalette());
BitmapBuffer* pWrite = rWinSalBitmap.AcquireBuffer(BITMAP_WRITE_ACCESS);
sal_uInt8* pSource(pRead->mpBits);
sal_uInt8* pDestination(pWrite->mpBits);
for (long y = 0; y < pRead->mnHeight; y++)
{
memcpy(pDestination, pSource, pRead->mnScanlineSize);
pSource += pRead->mnScanlineSize;
pDestination += pWrite->mnScanlineSize;
}
rWinSalBitmap.ReleaseBuffer(pWrite, BITMAP_WRITE_ACCESS);
rSalBitmap.ReleaseBuffer(pRead, BITMAP_READ_ACCESS);
}
} // end anonymous namespace
void WinSalGraphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap) void WinSalGraphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap)
{ {
mpImpl->drawBitmap( rPosAry, rSalBitmap ); if (dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get()) == nullptr &&
dynamic_cast<const WinSalBitmap*>(&rSalBitmap) == nullptr)
{
std::unique_ptr<WinSalBitmap> pWinSalBitmap(new WinSalBitmap());
SalBitmap& rConstBitmap = const_cast<SalBitmap&>(rSalBitmap);
convertToWinSalBitmap(rConstBitmap, *pWinSalBitmap.get());
mpImpl->drawBitmap(rPosAry, *pWinSalBitmap.get());
}
else
{
mpImpl->drawBitmap(rPosAry, rSalBitmap);
}
} }
void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry, void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry,
const SalBitmap& rSSalBitmap, const SalBitmap& rSSalBitmap,
SalColor nTransparentColor ) SalColor nTransparentColor )
{ {
mpImpl->drawBitmap( rPosAry, rSSalBitmap, nTransparentColor ); if (dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get()) == nullptr &&
dynamic_cast<const WinSalBitmap*>(&rSSalBitmap) == nullptr)
{
std::unique_ptr<WinSalBitmap> pWinSalBitmap(new WinSalBitmap());
SalBitmap& rConstBitmap = const_cast<SalBitmap&>(rSSalBitmap);
convertToWinSalBitmap(rConstBitmap, *pWinSalBitmap.get());
mpImpl->drawBitmap(rPosAry, *pWinSalBitmap.get(), nTransparentColor);
}
else
{
mpImpl->drawBitmap(rPosAry, rSSalBitmap, nTransparentColor);
}
} }
void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry, void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry,
const SalBitmap& rSSalBitmap, const SalBitmap& rSSalBitmap,
const SalBitmap& rSTransparentBitmap ) const SalBitmap& rSTransparentBitmap )
{ {
mpImpl->drawBitmap( rPosAry, rSSalBitmap, rSTransparentBitmap ); if (dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get()) == nullptr &&
dynamic_cast<const WinSalBitmap*>(&rSSalBitmap) == nullptr)
{
std::unique_ptr<WinSalBitmap> pWinSalBitmap(new WinSalBitmap());
SalBitmap& rConstBitmap = const_cast<SalBitmap&>(rSSalBitmap);
convertToWinSalBitmap(rConstBitmap, *pWinSalBitmap.get());
std::unique_ptr<WinSalBitmap> pWinTransparentSalBitmap(new WinSalBitmap());
SalBitmap& rConstTransparentBitmap = const_cast<SalBitmap&>(rSTransparentBitmap);
convertToWinSalBitmap(rConstTransparentBitmap, *pWinTransparentSalBitmap.get());
mpImpl->drawBitmap(rPosAry, *pWinSalBitmap.get(), *pWinTransparentSalBitmap.get());
}
else
{
mpImpl->drawBitmap(rPosAry, rSSalBitmap, rSTransparentBitmap);
}
} }
bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment