[Libreoffice-commits] core.git: include/vcl vcl/opengl vcl/source

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Tue Apr 16 11:44:31 UTC 2019


 include/vcl/opengl/OpenGLHelper.hxx |   11 ++++++++---
 vcl/opengl/texture.cxx              |    4 ++--
 vcl/source/opengl/OpenGLHelper.cxx  |   30 +++++++++++++++++++++++++++---
 3 files changed, 37 insertions(+), 8 deletions(-)

New commits:
commit 0555bda4856626f520a14c33fa5ba8ff8dcb0ac8
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Sun Apr 14 18:21:04 2019 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Tue Apr 16 13:43:45 2019 +0200

    make ConvertBGRABufferToBitmapEx work properly also on non-win32
    
    Windows uses GL_BGRA, but e.g. on Linux OpenGL stores as GL_RGBA.
    
    Change-Id: I00820f7b7a16a54b10c682ba332627ec04648508
    Reviewed-on: https://gerrit.libreoffice.org/70772
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/include/vcl/opengl/OpenGLHelper.hxx b/include/vcl/opengl/OpenGLHelper.hxx
index 9475aeb09355..861af021a383 100644
--- a/include/vcl/opengl/OpenGLHelper.hxx
+++ b/include/vcl/opengl/OpenGLHelper.hxx
@@ -55,10 +55,15 @@ public:
     static GLint LoadShaders(const OUString& rVertexShaderName, const OUString& rFragmentShaderName);
 
     /**
-     * The caller is responsible for allocate the memory for the RGBA buffer, before call
-     * this method. RGBA buffer size is assumed to be 4*width*height.
+     * The caller is responsible for allocating the memory for the buffer before calling
+     * this method. The buffer size is assumed to be 4*width*height and the format
+     * to be OptimalBufferFormat().
     **/
-    static BitmapEx ConvertBGRABufferToBitmapEx(const sal_uInt8* const pBuffer, long nWidth, long nHeight);
+    static BitmapEx ConvertBufferToBitmapEx(const sal_uInt8* const pBuffer, long nWidth, long nHeight);
+    /**
+     * Returns the optimal buffer format for OpenGL (GL_BGRA or GL_RGBA).
+    **/
+    static GLenum OptimalBufferFormat();
     static void renderToFile(long nWidth, long nHeight, const OUString& rFileName);
 
     static const char* GLErrorString(GLenum errorCode);
diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx
index 6536141c8134..19b48967e314 100644
--- a/vcl/opengl/texture.cxx
+++ b/vcl/opengl/texture.cxx
@@ -498,8 +498,8 @@ void OpenGLTexture::Unbind()
 void OpenGLTexture::SaveToFile(const OUString& rFileName)
 {
     std::vector<sal_uInt8> aBuffer(GetWidth() * GetHeight() * 4);
-    Read(GL_BGRA, GL_UNSIGNED_BYTE, aBuffer.data());
-    BitmapEx aBitmap = OpenGLHelper::ConvertBGRABufferToBitmapEx(aBuffer.data(), GetWidth(), GetHeight());
+    Read(OpenGLHelper::OptimalBufferFormat(), GL_UNSIGNED_BYTE, aBuffer.data());
+    BitmapEx aBitmap = OpenGLHelper::ConvertBufferToBitmapEx(aBuffer.data(), GetWidth(), GetHeight());
     try
     {
         vcl::PNGWriter aWriter(aBitmap);
diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx
index b21619e18b46..2b2e8ea4d783 100644
--- a/vcl/source/opengl/OpenGLHelper.cxx
+++ b/vcl/source/opengl/OpenGLHelper.cxx
@@ -541,8 +541,8 @@ void OpenGLHelper::renderToFile(long nWidth, long nHeight, const OUString& rFile
     OpenGLZone aZone;
 
     std::unique_ptr<sal_uInt8[]> pBuffer(new sal_uInt8[nWidth*nHeight*4]);
-    glReadPixels(0, 0, nWidth, nHeight, GL_BGRA, GL_UNSIGNED_BYTE, pBuffer.get());
-    BitmapEx aBitmap = ConvertBGRABufferToBitmapEx(pBuffer.get(), nWidth, nHeight);
+    glReadPixels(0, 0, nWidth, nHeight, OptimalBufferFormat(), GL_UNSIGNED_BYTE, pBuffer.get());
+    BitmapEx aBitmap = ConvertBufferToBitmapEx(pBuffer.get(), nWidth, nHeight);
     try {
         vcl::PNGWriter aWriter( aBitmap );
         SvFileStream sOutput( rFileName, StreamMode::WRITE );
@@ -555,7 +555,16 @@ void OpenGLHelper::renderToFile(long nWidth, long nHeight, const OUString& rFile
     CHECK_GL_ERROR();
 }
 
-BitmapEx OpenGLHelper::ConvertBGRABufferToBitmapEx(const sal_uInt8* const pBuffer, long nWidth, long nHeight)
+GLenum OpenGLHelper::OptimalBufferFormat()
+{
+#ifdef _WIN32
+    return GL_BGRA; // OpenGLSalBitmap is internally ScanlineFormat::N24BitTcBgr
+#else
+    return GL_RGBA; // OpenGLSalBitmap is internally ScanlineFormat::N24BitTcRgb
+#endif
+}
+
+BitmapEx OpenGLHelper::ConvertBufferToBitmapEx(const sal_uInt8* const pBuffer, long nWidth, long nHeight)
 {
     assert(pBuffer);
     Bitmap aBitmap( Size(nWidth, nHeight), 24 );
@@ -564,12 +573,27 @@ BitmapEx OpenGLHelper::ConvertBGRABufferToBitmapEx(const sal_uInt8* const pBuffe
     {
         BitmapScopedWriteAccess pWriteAccess( aBitmap );
         AlphaScopedWriteAccess pAlphaWriteAccess( aAlpha );
+#ifdef _WIN32
+        assert(pWriteAccess->GetScanlineFormat() == ScanlineFormat::N24BitTcBgr);
+        assert(pWriteAccess->IsTopDown());
+        assert(pAlphaWriteAccess->IsTopDown());
+#else
+        assert(pWriteAccess->GetScanlineFormat() == ScanlineFormat::N24BitTcRgb);
+        assert(!pWriteAccess->IsTopDown());
+        assert(!pAlphaWriteAccess->IsTopDown());
+#endif
+        assert(pAlphaWriteAccess->GetScanlineFormat() == ScanlineFormat::N8BitPal);
 
         size_t nCurPos = 0;
         for( long y = 0; y < nHeight; ++y)
         {
+#ifdef _WIN32
             Scanline pScan = pWriteAccess->GetScanline(y);
             Scanline pAlphaScan = pAlphaWriteAccess->GetScanline(y);
+#else
+            Scanline pScan = pWriteAccess->GetScanline(nHeight-1-y);
+            Scanline pAlphaScan = pAlphaWriteAccess->GetScanline(nHeight-1-y);
+#endif
             for( long x = 0; x < nWidth; ++x )
             {
                 *pScan++ = pBuffer[nCurPos];


More information about the Libreoffice-commits mailing list