summaryrefslogtreecommitdiff
path: root/vcl/opengl/salbmp.cxx
diff options
context:
space:
mode:
authorMarco Cecchetti <marco.cecchetti@collabora.com>2015-08-26 13:50:57 +0200
committerMichael Meeks <michael.meeks@collabora.com>2015-09-01 16:28:45 +0100
commitebb0dc14547e698d7b53005178063da72d48f075 (patch)
tree8cf95d717f32672dc8e6ecf9f6b743227ada889f /vcl/opengl/salbmp.cxx
parent7cc4cdc5ef6dff279e072af725c2d7fc1e5da0e8 (diff)
Added support for computing 64-bit checksum of bitmap in OpenGL
Added a C++ and a GLSL implementation of a 64-bit CRC algorithm. Changed hardcoded checksum value in ooxmlimport unit test (testN777345). Change-Id: I16bb985a14866775efda49e21fe033ff64645896
Diffstat (limited to 'vcl/opengl/salbmp.cxx')
-rw-r--r--vcl/opengl/salbmp.cxx90
1 files changed, 90 insertions, 0 deletions
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
index d6e51d9bfd72..8ab721e25f6c 100644
--- a/vcl/opengl/salbmp.cxx
+++ b/vcl/opengl/salbmp.cxx
@@ -31,6 +31,7 @@
#include "opengl/program.hxx"
#include "opengl/salbmp.hxx"
+#include "../inc/checksum.hxx"
#include "opengl/FixedTextureAtlas.hxx"
namespace
@@ -508,6 +509,94 @@ sal_uInt16 OpenGLSalBitmap::GetBitCount() const
return mnBits;
}
+bool OpenGLSalBitmap::calcChecksumGL(OpenGLTexture& rInputTexture, ChecksumType& rChecksum) const
+{
+ OUString FragShader("areaHashCRC64TFragmentShader");
+
+ static const OpenGLTexture aCRCTableTexture(512, 1, GL_RGBA, GL_UNSIGNED_BYTE,
+ (sal_uInt8*)(vcl_crc64Table));
+
+ // First Pass
+
+ int nWidth = rInputTexture.GetWidth();
+ int nHeight = rInputTexture.GetHeight();
+
+ OpenGLProgram* pProgram = mpContext->UseProgram("textureVertexShader", FragShader);
+ if (pProgram == 0)
+ return false;
+
+ int nNewWidth = ceil( nWidth / 4.0 );
+ int nNewHeight = ceil( nHeight / 4.0 );
+
+ OpenGLTexture aFirstPassTexture = OpenGLTexture(nNewWidth, nNewHeight);
+ OpenGLFramebuffer* pFramebuffer = mpContext->AcquireFramebuffer(aFirstPassTexture);
+
+ pProgram->SetUniform1f( "xstep", 1.0 / mnWidth );
+ pProgram->SetUniform1f( "ystep", 1.0 / mnHeight );
+
+ pProgram->SetTexture("crc_table", (OpenGLTexture&)(aCRCTableTexture));
+ pProgram->SetTexture("sampler", rInputTexture);
+ pProgram->DrawTexture(rInputTexture);
+ pProgram->Clean();
+
+ OpenGLContext::ReleaseFramebuffer(pFramebuffer);
+
+ CHECK_GL_ERROR();
+
+
+ // Second Pass
+
+ nWidth = aFirstPassTexture.GetWidth();
+ nHeight = aFirstPassTexture.GetHeight();
+
+ pProgram = mpContext->UseProgram("textureVertexShader", FragShader);
+ if (pProgram == 0)
+ return false;
+
+ nNewWidth = ceil( nWidth / 4.0 );
+ nNewHeight = ceil( nHeight / 4.0 );
+
+ OpenGLTexture aSecondPassTexture = OpenGLTexture(nNewWidth, nNewHeight);
+ pFramebuffer = mpContext->AcquireFramebuffer(aSecondPassTexture);
+
+ pProgram->SetUniform1f( "xstep", 1.0 / mnWidth );
+ pProgram->SetUniform1f( "ystep", 1.0 / mnHeight );
+
+ pProgram->SetTexture("crc_table", (OpenGLTexture&)(aCRCTableTexture));
+ pProgram->SetTexture("sampler", aFirstPassTexture);
+ pProgram->DrawTexture(aFirstPassTexture);
+ pProgram->Clean();
+
+ OpenGLContext::ReleaseFramebuffer(pFramebuffer);
+
+ CHECK_GL_ERROR();
+
+ // Final CRC on CPU
+ OpenGLTexture& aFinalTexture = aSecondPassTexture;
+ std::vector<sal_uInt8> aBuf( aFinalTexture.GetWidth() * aFinalTexture.GetHeight() * 4 );
+ aFinalTexture.Read(GL_RGBA, GL_UNSIGNED_BYTE, aBuf.data());
+
+ ChecksumType nCrc = vcl_crc64(0, aBuf.data(), aBuf.size());
+
+ rChecksum = nCrc;
+ return true;
+}
+
+void OpenGLSalBitmap::updateChecksum() const
+{
+ if (mbChecksumValid)
+ return;
+
+ OpenGLSalBitmap* pThis = const_cast<OpenGLSalBitmap*>(this);
+
+ if (!mpContext)
+ {
+ pThis->CreateTexture();
+ }
+
+ pThis->mbChecksumValid = calcChecksumGL(pThis->maTexture, pThis->maChecksum);
+}
+
OpenGLContext* OpenGLSalBitmap::GetBitmapContext()
{
return ImplGetDefaultWindow()->GetGraphics()->GetOpenGLContext();
@@ -581,6 +670,7 @@ void OpenGLSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMo
{
maTexture = OpenGLTexture();
mbDirtyTexture = true;
+ mbChecksumValid = false;
}
// The palette is modified on read during the BitmapWriteAccess,
// but of course, often it is not modified; interesting.