Revision: 3522
http://hugin.svn.sourceforge.net/hugin/?rev=3522&view=rev
Author: acmihal
Date: 2008-10-25 18:38:29 +0000 (Sat, 25 Oct 2008)
Log Message:
-----------
Direct image data buffer access with 8-byte alignment for fast GPU transfers.
Modified Paths:
--------------
hugin/branches/nona-gpu/src/hugin_base/nona/ImageRemapper.h
hugin/branches/nona-gpu/src/hugin_base/nona/RemappedPanoImage.h
hugin/branches/nona-gpu/src/hugin_base/vigra_ext/ImageTransforms.h
hugin/branches/nona-gpu/src/hugin_base/vigra_ext/ImageTransformsGPU.cpp
hugin/branches/nona-gpu/src/hugin_base/vigra_ext/ImageTransformsGPU.h
Modified: hugin/branches/nona-gpu/src/hugin_base/nona/ImageRemapper.h
===================================================================
--- hugin/branches/nona-gpu/src/hugin_base/nona/ImageRemapper.h 2008-10-25 12:44:36 UTC (rev 3521)
+++ hugin/branches/nona-gpu/src/hugin_base/nona/ImageRemapper.h 2008-10-25 18:38:29 UTC (rev 3522)
@@ -187,11 +187,21 @@
// load image
vigra::ImageImportInfo info(img.getFilename().c_str());
- ImageType srcImg(info.width(), info.height());
+
+ int width = info.width();
+ int height = info.height();
+
+ if (opts.remapUsingGPU) {
+ // Extend image width to multiple of 8 for fast GPU transfers.
+ const int r = width % 8;
+ if (r != 0) width += 8 - r;
+ }
+
+ ImageType srcImg(width, height);
m_remapped->m_ICCProfile = info.getICCProfile();
if (info.numExtraBands() > 0) {
- srcAlpha.resize(info.width(), info.height());
+ srcAlpha.resize(width, height);
}
//int nb = info.numBands() - info.numExtraBands();
bool alpha = info.numExtraBands() > 0;
Modified: hugin/branches/nona-gpu/src/hugin_base/nona/RemappedPanoImage.h
===================================================================
--- hugin/branches/nona-gpu/src/hugin_base/nona/RemappedPanoImage.h 2008-10-25 12:44:36 UTC (rev 3521)
+++ hugin/branches/nona-gpu/src/hugin_base/nona/RemappedPanoImage.h 2008-10-25 18:38:29 UTC (rev 3522)
@@ -221,6 +221,13 @@
// restrict to panorama size
m_srcImg = src;
m_destImg = dest;
+
+ if (m_destImg.remapUsingGPU) {
+ // Make width multiple of 8 for fast GPU transfers.
+ const int r = roi.width() % 8;
+ if (r != 0) roi.addSize(vigra::Size2D(8 - r, 0));
+ }
+
Base::resize(roi);
m_transf.createTransform(src, dest);
@@ -421,8 +428,15 @@
return;
vigra::Diff2D srcImgSize = srcImg.second - srcImg.first;
+
+ vigra::Size2D expectedSize = m_srcImg.getSize();
+ if (useGPU) {
+ const int r = expectedSize.width() % 8;
+ if (r != 0) expectedSize += vigra::Diff2D(8 - r, 0);
+ }
+
DEBUG_DEBUG("srcImgSize: " << srcImgSize << " m_srcImgSize: " << m_srcImg.getSize());
- vigra_precondition(srcImgSize == m_srcImg.getSize(),
+ vigra_precondition(srcImgSize == expectedSize,
"RemappedPanoImage<RemapImage,AlphaImage>::remapImage(): image sizes not consistent");
typedef typename ImgAccessor::value_type input_value_type;
@@ -547,7 +561,13 @@
vigra::Diff2D srcImgSize = srcImg.second - srcImg.first;
- vigra_precondition(srcImgSize == m_srcImg.getSize(),
+ vigra::Size2D expectedSize = m_srcImg.getSize();
+ if (useGPU) {
+ const int r = expectedSize.width() % 8;
+ if (r != 0) expectedSize += vigra::Diff2D(8 - r, 0);
+ }
+
+ vigra_precondition(srcImgSize == expectedSize,
"RemappedPanoImage<RemapImage,AlphaImage>::remapImage(): image sizes not consistent");
typedef typename ImgAccessor::value_type input_value_type;
Modified: hugin/branches/nona-gpu/src/hugin_base/vigra_ext/ImageTransforms.h
===================================================================
--- hugin/branches/nona-gpu/src/hugin_base/vigra_ext/ImageTransforms.h 2008-10-25 12:44:36 UTC (rev 3521)
+++ hugin/branches/nona-gpu/src/hugin_base/vigra_ext/ImageTransforms.h 2008-10-25 18:38:29 UTC (rev 3522)
@@ -27,7 +27,6 @@
#ifndef _VIGRA_EXT_IMAGETRANSFORMS_H
#define _VIGRA_EXT_IMAGETRANSFORMS_H
-#include <iostream>
#include <fstream>
#include <vigra/basicimage.hxx>
@@ -44,9 +43,6 @@
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
-#include <sys/time.h>
-#include <time.h>
-
namespace vigra_ext
{
@@ -90,9 +86,6 @@
bool warparound,
AppBase::MultiProgressDisplay & prog)
{
- timeval t0;
- gettimeofday(&t0, NULL);
-
vigra::Diff2D destSize = dest.second - dest.first;
int xstart = destUL.x;
@@ -141,10 +134,6 @@
}
}
prog.popTask();
-
- timeval t1;
- gettimeofday(&t1, NULL);
- std::cout << "deltaT=" << (t1.tv_sec - t0.tv_sec + 1e-6*(t1.tv_usec - t0.tv_usec)) << std::endl;
}
Modified: hugin/branches/nona-gpu/src/hugin_base/vigra_ext/ImageTransformsGPU.cpp
===================================================================
--- hugin/branches/nona-gpu/src/hugin_base/vigra_ext/ImageTransformsGPU.cpp 2008-10-25 12:44:36 UTC (rev 3521)
+++ hugin/branches/nona-gpu/src/hugin_base/vigra_ext/ImageTransformsGPU.cpp 2008-10-25 18:38:29 UTC (rev 3522)
@@ -24,6 +24,7 @@
*/
#include <iostream>
+#include <iomanip>
#define GLEW_STATIC
#include <GL/glew.h>
@@ -32,12 +33,28 @@
#include <sys/time.h>
#include <time.h>
+#include <vigra/diff2d.hxx>
+#include <vigra/error.hxx>
+
using std::cout;
using std::cerr;
using std::endl;
#define CHECK_GL() checkGLErrors(__LINE__, __FILE__)
+static GLenum XGLMap[] = {GL_RED, GL_RGB, GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT, GL_FLOAT};
+
+static const char *AlphaCombineKernelSource = {
+"#extension GL_ARB_texture_rectangle : enable"
+"uniform sampler2DRect SrcAlphaTexture;"
+"void main(void)"
+"{"
+" float alpha = texture2DRect(SrcAlphaTexture, gl_TexCoord[0].st);"
+" if (alpha != 0.0) discard;"
+" gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);"
+"}"
+};
+
static void checkGLErrors(int line, char *file) {
GLenum errCode;
if ((errCode = glGetError()) != GL_NO_ERROR) {
@@ -95,32 +112,170 @@
{
bool transformImageGPUIntern(const std::string& glsl,
- const int srcWidth, const int srcHeight,
- float* const srcBuffer,
- const int destXStart, const int destXEnd,
- const int destYStart, const int destYEnd,
- const int destWidth, const int destHeight,
- float* const destBuffer,
- const bool warparound) {
+ const vigra::Diff2D srcSize,
+ const void* const srcBuffer,
+ const int srcGLType, const int srcGLFormat,
+ const void* const srcAlphaBuffer,
+ const int srcAlphaGLType, const int srcAlphaGLFormat,
+ const vigra::Diff2D destUL,
+ const vigra::Diff2D destSize,
+ void* const destBuffer,
+ const int destGLType, const int destGLFormat,
+ void* const destAlphaBuffer,
+ const int destAlphaGLType, const int destAlphaGLFormat,
+ const bool warparound)
+{
+ const int xstart = destUL.x;
+ const int xend = destUL.x + destSize.x;
+ const int ystart = destUL.y;
+ const int yend = destUL.y + destSize.y;
- timeval t0;
- gettimeofday(&t0, NULL);
+ cout << "destStart=[" << xstart << ", " << ystart << "]" << endl
+ << "destEnd=[" << xend << ", " << yend << "]" << endl
+ << "destSize=[" << destSize << "]" << endl
+ << "srcSize=[" << srcSize << "]" << endl;
- const char* glslCString = glsl.c_str();
- cout << glslCString;
+ vigra_precondition((srcSize.x % 8) == 0, "src image width not a multiple of 8");
+ vigra_precondition((destSize.x % 8) == 0, "dest image width not a multiple of 8");
- cout << "destStart=[" << destXStart << ", " << destYStart << "]" << endl
- << "destEnd=[" << destXEnd << ", " << destYEnd << "]" << endl
- << "destSize=[" << destWidth << ", " << destHeight << "]" << endl
- << "srcSize=[" << srcWidth << ", " << srcHeight << "]" << endl;
+ cout << "srcBuffer=" << srcBuffer << endl
+ << "srcAlphaBuffer=" << srcAlphaBuffer << endl
+ << "destBuffer=" << destBuffer << endl
+ << "destAlphaBuffer=" << destAlphaBuffer << endl;
+ vigra_precondition((reinterpret_cast<const uintptr_t>(srcBuffer) & 0x7) == 0, "src image buffer not 8-byte aligned");
+ vigra_precondition((reinterpret_cast<const uintptr_t>(srcAlphaBuffer) & 0x7) == 0, "src alpha image buffer not 8-byte aligned");
+ vigra_precondition((reinterpret_cast<const uintptr_t>(destBuffer) & 0x7) == 0, "dest image buffer not 8-byte aligned");
+ vigra_precondition((reinterpret_cast<const uintptr_t>(destAlphaBuffer) & 0x7) == 0, "dest alpha image buffer not 8-byte aligned");
+
+ cout << "destGLFormat=" << destGLFormat << endl
+ << "destGLType=" << destGLType << endl
+ << "srcGLFormat=" << srcGLFormat << endl
+ << "srcGLType=" << srcGLType << endl
+ << "srcAlphaGLFormat=" << srcAlphaGLFormat << endl
+ << "srcAlphaGLType=" << srcAlphaGLType << endl
+ << "destAlphaGLFormat=" << destAlphaGLFormat << endl
+ << "destAlphaGLType=" << destAlphaGLType << endl;
+
+ std::ostringstream oss;
+ oss << std::setprecision(20) << std::showpoint;
+ oss << "#extension GL_ARB_texture_rectangle : enable" << endl
+ << "#version 110" << endl
+ << "uniform sampler2DRect SrcTexture;" << endl
+ << "vec2 sinc(const in vec2 x) {" << endl
+ << " vec2 xpi = x * " << M_PI << ";" << endl
+ << " vec2 result = vec2(1.0, 1.0);" << endl
+ << " if (xpi.s != 0.0) result.s = sin(xpi.s) / xpi.s;" << endl
+ << " if (xpi.t != 0.0) result.t = sin(xpi.t) / xpi.t;" << endl
+ << " return result;" << endl
+ << "}" << endl
+ << "float sinh(const in float x) { return (exp(x) - exp(-x)) / 2.0; }" << endl
+ << "float cosh(const in float x) { return (exp(x) + exp(-x)) / 2.0; }" << endl
+ << "void main(void)" << endl
+ << "{" << endl
+ << glsl
+ << " gl_FragColor = p;" << endl
+ << "}" << endl;
+
+ std::string ossStr = oss.str();
+ const char* remapKernelSource = ossStr.c_str();
+ cout << remapKernelSource;
+
GLint maxTextureSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
cout << "maxTextureSize=" << maxTextureSize << endl;
+ glPixelStorei(GL_PACK_ALIGNMENT, 8);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
+
+ GLuint srcTexture;
+ glGenTextures(1, &srcTexture);
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, srcTexture);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, (warparound) ? GL_REPEAT : GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F_ARB, srcSize.x, srcSize.y, 0, XGLMap[srcGLFormat], XGLMap[srcGLType], srcBuffer);
+ CHECK_GL();
+
+ if (srcAlphaBuffer != NULL) {
+ static bool createdAlphaShader = false;
+ static GLhandleARB alphaProgramObject;
+ static GLhandleARB alphaShaderObject;
+ static GLint srcAlphaTextureParam;
+
+ if (!createdAlphaShader) {
+ alphaProgramObject = glCreateProgramObjectARB();
+ alphaShaderObject = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
+ glShaderSourceARB(alphaShaderObject, 1, &AlphaCombineKernelSource, NULL);
+ glCompileShaderARB(alphaShaderObject);
+ printInfoLog(alphaShaderObject);
+ glAttachObjectARB(alphaProgramObject, alphaShaderObject);
+ glLinkProgramARB(alphaProgramObject);
+ GLint success;
+ glGetObjectParameterivARB(alphaProgramObject, GL_OBJECT_LINK_STATUS_ARB, &success);
+ if (!success) {
+ printInfoLog(alphaProgramObject);
+ cerr << "nona: GPU alpha combine shader program could not be linked." << endl;
+ exit(1);
+ }
+ srcAlphaTextureParam = glGetUniformLocationARB(alphaProgramObject, "SrcAlphaTexture");
+ createdAlphaShader = true;
+ }
+
+ glUseProgramObjectARB(alphaProgramObject);
+
+ GLuint srcAlphaTexture;
+ glGenTextures(1, &srcAlphaTexture);
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, srcAlphaTexture);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE32F_ARB, srcSize.x, srcSize.y, 0, XGLMap[srcAlphaGLFormat], XGLMap[srcAlphaGLType], srcAlphaBuffer);
+ CHECK_GL();
+
+ GLuint afb;
+ glGenFramebuffersEXT(1, &afb);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, afb);
+
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, srcTexture, 0);
+
+ if (!checkFramebufferStatus()) {
+ exit(1);
+ }
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(0.0, srcSize.x, 0.0, srcSize.y);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glViewport(0, 0, srcSize.x, srcSize.y);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, srcAlphaTexture);
+ glUniform1iARB(srcAlphaTextureParam, 0);
+ CHECK_GL();
+
+ glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ glPolygonMode(GL_FRONT, GL_FILL);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0);
+ glTexCoord2f(srcSize.x, 0.0); glVertex2f(srcSize.x, 0.0);
+ glTexCoord2f(srcSize.x, srcSize.y); glVertex2f(srcSize.x, srcSize.y);
+ glTexCoord2f(0.0, srcSize.y); glVertex2f(0.0, srcSize.y);
+ glEnd();
+ CHECK_GL();
+
+ glDeleteFramebuffersEXT(1, &afb);
+ glDeleteTextures(1, &srcAlphaTexture);
+ }
+
GLhandleARB programObject = glCreateProgramObjectARB();
GLhandleARB shaderObject = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
- glShaderSourceARB(shaderObject, 1, &glslCString, NULL);
+ glShaderSourceARB(shaderObject, 1, &remapKernelSource, NULL);
glCompileShaderARB(shaderObject);
printInfoLog(shaderObject);
glAttachObjectARB(programObject, shaderObject);
@@ -129,7 +284,7 @@
glGetObjectParameterivARB(programObject, GL_OBJECT_LINK_STATUS_ARB, &success);
if (!success) {
printInfoLog(programObject);
- cerr << "nona: GPU ARB shader program could not be linked." << endl;
+ cerr << "nona: GPU remap shader program could not be linked." << endl;
exit(1);
}
@@ -137,16 +292,6 @@
glUseProgramObjectARB(programObject);
- GLuint srcTexture;
- glGenTextures(1, &srcTexture);
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, srcTexture);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, (warparound) ? GL_REPEAT : GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
- glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F_ARB, srcWidth, srcHeight, 0, GL_RGBA, GL_FLOAT, NULL);
- CHECK_GL();
-
GLuint outTexture;
glGenTextures(1, &outTexture);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, outTexture);
@@ -154,20 +299,12 @@
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
- glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F_ARB, destWidth, destHeight, 0, GL_RGBA, GL_FLOAT, NULL);
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F_ARB, destSize.x, destSize.y, 0, XGLMap[destGLFormat], XGLMap[destGLType], NULL);
CHECK_GL();
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
GLuint fb;
glGenFramebuffersEXT(1, &fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluOrtho2D(0.0, destWidth, 0.0, destHeight);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glViewport(0, 0, destWidth, destHeight);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, outTexture, 0);
@@ -175,10 +312,15 @@
exit(1);
}
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, srcTexture);
- glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, srcWidth, srcHeight, GL_RGBA, GL_FLOAT, srcBuffer);
- CHECK_GL();
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(0.0, destSize.x, 0.0, destSize.y);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glViewport(0, 0, destSize.x, destSize.y);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, srcTexture);
glUniform1iARB(srcTextureParam, 0);
@@ -190,10 +332,10 @@
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glPolygonMode(GL_FRONT, GL_FILL);
glBegin(GL_QUADS);
- glTexCoord2f(destXStart, destYStart); glVertex2f(0.0, 0.0);
- glTexCoord2f(destXEnd, destYStart); glVertex2f(destWidth, 0.0);
- glTexCoord2f(destXEnd, destYEnd); glVertex2f(destWidth, destHeight);
- glTexCoord2f(destXStart, destYEnd); glVertex2f(0.0, destHeight);
+ glTexCoord2f(xstart, ystart); glVertex2f(0.0, 0.0);
+ glTexCoord2f(xend, ystart); glVertex2f(destSize.x, 0.0);
+ glTexCoord2f(xend, yend); glVertex2f(destSize.x, destSize.y);
+ glTexCoord2f(xstart, yend); glVertex2f(0.0, destSize.y);
glEnd();
CHECK_GL();
@@ -206,15 +348,12 @@
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
CHECK_GL();
- timeval t3;
- gettimeofday(&t3, NULL);
+ glReadPixels(0, 0, destSize.x, destSize.y, XGLMap[destGLFormat], XGLMap[destGLType], destBuffer);
+ CHECK_GL();
- glReadPixels(0, 0, destWidth, destHeight, GL_RGBA, GL_FLOAT, destBuffer);
+ glReadPixels(0, 0, destSize.x, destSize.y, GL_ALPHA, XGLMap[destAlphaGLType], destAlphaBuffer);
CHECK_GL();
- timeval t4;
- gettimeofday(&t4, NULL);
-
glDeleteFramebuffersEXT(1, &fb);
glDeleteTextures(1, &outTexture);
glDeleteTextures(1, &srcTexture);
@@ -223,10 +362,7 @@
glDeleteObjectARB(shaderObject);
glDeleteObjectARB(programObject);
- cout << "t1-t0=" << (t1.tv_sec - t0.tv_sec + 1e-6*(t1.tv_usec - t0.tv_usec)) << endl;
- cout << "t2-t1=" << (t2.tv_sec - t1.tv_sec + 1e-6*(t2.tv_usec - t1.tv_usec)) << endl;
- cout << "t3-t2=" << (t3.tv_sec - t2.tv_sec + 1e-6*(t3.tv_usec - t2.tv_usec)) << endl;
- cout << "t4-t3=" << (t4.tv_sec - t3.tv_sec + 1e-6*(t4.tv_usec - t3.tv_usec)) << endl;
+ cout << "gpu render time = " << (t2.tv_sec - t1.tv_sec + 1e-6*(t2.tv_usec - t1.tv_usec)) << endl;
return true;
}
Modified: hugin/branches/nona-gpu/src/hugin_base/vigra_ext/ImageTransformsGPU.h
===================================================================
--- hugin/branches/nona-gpu/src/hugin_base/vigra_ext/ImageTransformsGPU.h 2008-10-25 12:44:36 UTC (rev 3521)
+++ hugin/branches/nona-gpu/src/hugin_base/vigra_ext/ImageTransformsGPU.h 2008-10-25 18:38:29 UTC (rev 3522)
@@ -52,99 +52,49 @@
{
bool transformImageGPUIntern(const std::string& glsl,
- const int srcWidth, const int srcHeight,
- float* const srcBuffer,
- const int destXStart, const int destXEnd,
- const int destYStart, const int destYEnd,
- const int destWidth, const int destHeight,
- float* const destBuffer,
+ const vigra::Diff2D srcSize,
+ const void* const srcBuffer,
+ const int srcGLType, const int srcGLFormat,
+ const void* const srcAlphaBuffer,
+ const int srcAlphaGLType, const int srcAlphaGLFormat,
+ const vigra::Diff2D destUL,
+ const vigra::Diff2D destSize,
+ void* const destBuffer,
+ const int destGLType, const int destGLFormat,
+ void* const destAlphaBuffer,
+ const int destAlphaGLType, const int destAlphaGLFormat,
const bool warparound);
-/* Wrappers to use the RGB GPU transform code for grayscale images.
- * The GPU uses vec4 pixel values so there is no point in specializing code
- * for single-channel images.
- */
+// This is to avoid including GL headers in this file.
+enum {XGL_RED=0, XGL_RGB, XGL_BYTE, XGL_UNSIGNED_BYTE, XGL_SHORT, XGL_UNSIGNED_SHORT, XGL_INT, XGL_UNSIGNED_INT, XGL_FLOAT};
-template <class SrcValueType>
-class ConvertToRGBValue {
-public:
- typedef typename vigra::RGBValue<SrcValueType, 0, 1, 2> result_type;
- result_type operator()(const SrcValueType& s) const {
- return result_type(s);
- }
+template <class A>
+struct GpuNumericTraits {
+ enum {ImagePixelComponentGLType = 0};
+ enum {ImageGLFormat = 0};
};
-template <class ResultValueType>
-class ConvertFromRGBValue {
-public:
- typedef typename vigra::RGBValue<ResultValueType, 0, 1, 2> SrcValueType;
- ResultValueType operator()(const SrcValueType& s) const {
- return ResultValueType(s.red());
- }
+#define DEFINE_GPUNUMERICTRAITS(IMAGECOMPONENT, GLTYPE) \
+template<> \
+struct GpuNumericTraits<IMAGECOMPONENT> { \
+ enum {ImagePixelComponentGLType = GLTYPE}; \
+ enum {ImageGLFormat = XGL_RED}; \
+}; \
+template<> \
+struct GpuNumericTraits<vigra::RGBValue<IMAGECOMPONENT, 0, 1, 2> > { \
+ enum {ImagePixelComponentGLType = GLTYPE}; \
+ enum {ImageGLFormat = XGL_RGB}; \
};
-
-template <class SrcImageIterator, class SrcAccessor,
- class DestImageIterator, class DestAccessor,
- class TRANSFORM,
- class PixelTransform,
- class AlphaImageIterator, class AlphaAccessor,
- class Interpolator>
-void transformImageGPUIntern(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
- vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
- std::pair<AlphaImageIterator, AlphaAccessor> alpha,
- TRANSFORM & transform,
- PixelTransform & pixelTransform,
- vigra::Diff2D destUL,
- Interpolator interp,
- bool warparound,
- AppBase::MultiProgressDisplay & prog,
- vigra::VigraTrueType)
-{
- typedef typename SrcAccessor::value_type SrcValueType;
- typedef typename vigra_ext::ReadFunctorAccessor<ConvertToRGBValue<SrcValueType>, SrcAccessor> RFAType;
- RFAType convert_sa(ConvertToRGBValue<SrcValueType>(), src.third);
- vigra::triple<SrcImageIterator, SrcImageIterator, RFAType> convert_src(src.first, src.second, convert_sa);
- typedef typename DestAccessor::value_type DestValueType;
- typedef typename vigra_ext::WriteFunctorAccessor<ConvertFromRGBValue<DestValueType>, DestAccessor, vigra::RGBValue<DestValueType, 0, 1, 2> > WFAType;
- WFAType convert_da(ConvertFromRGBValue<DestValueType>(), dest.third);
- vigra::triple<DestImageIterator, DestImageIterator, WFAType> convert_dest(dest.first, dest.second, convert_da);
+DEFINE_GPUNUMERICTRAITS(vigra::Int8, XGL_BYTE);
+DEFINE_GPUNUMERICTRAITS(vigra::UInt8, XGL_UNSIGNED_BYTE);
+DEFINE_GPUNUMERICTRAITS(vigra::Int16, XGL_SHORT);
+DEFINE_GPUNUMERICTRAITS(vigra::UInt16, XGL_UNSIGNED_SHORT);
+DEFINE_GPUNUMERICTRAITS(vigra::Int32, XGL_INT);
+DEFINE_GPUNUMERICTRAITS(vigra::UInt32, XGL_UNSIGNED_INT);
+DEFINE_GPUNUMERICTRAITS(float, XGL_FLOAT);
- transformImageGPUIntern(convert_src, convert_dest, alpha, transform, pixelTransform, destUL, interp, warparound, prog, vigra::VigraFalseType());
-}
-template <class SrcImageIterator, class SrcAccessor,
- class SrcAlphaIterator, class SrcAlphaAccessor,
- class DestImageIterator, class DestAccessor,
- class TRANSFORM,
- class PixelTransform,
- class AlphaImageIterator, class AlphaAccessor,
- class Interpolator>
-void transformImageAlphaGPUIntern(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
- std::pair<SrcAlphaIterator, SrcAlphaAccessor> srcAlpha,
- vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
- std::pair<AlphaImageIterator, AlphaAccessor> alpha,
- TRANSFORM & transform,
- PixelTransform & pixelTransform,
- vigra::Diff2D destUL,
- Interpolator interp,
- bool warparound,
- AppBase::MultiProgressDisplay & prog,
- vigra::VigraTrueType)
-{
- typedef typename SrcAccessor::value_type SrcValueType;
- typedef typename vigra_ext::ReadFunctorAccessor<ConvertToRGBValue<SrcValueType>, SrcAccessor> RFAType;
- RFAType convert_sa(ConvertToRGBValue<SrcValueType>(), src.third);
- vigra::triple<SrcImageIterator, SrcImageIterator, RFAType> convert_src(src.first, src.second, convert_sa);
-
- typedef typename DestAccessor::value_type DestValueType;
- typedef typename vigra_ext::WriteFunctorAccessor<ConvertFromRGBValue<DestValueType>, DestAccessor, vigra::RGBValue<DestValueType, 0, 1, 2> > WFAType;
- WFAType convert_da(ConvertFromRGBValue<DestValueType>(), dest.third);
- vigra::triple<DestImageIterator, DestImageIterator, WFAType> convert_dest(dest.first, dest.second, convert_da);
-
- transformImageAlphaGPUIntern(convert_src, srcAlpha, convert_dest, alpha, transform, pixelTransform, destUL, interp, warparound, prog, vigra::VigraFalseType());
-}
-
/** Transform an image into the panorama
*
* Uses the GPU for processing.
@@ -185,24 +135,17 @@
vigra::Diff2D destUL,
Interpolator interp,
bool warparound,
- AppBase::MultiProgressDisplay & prog,
- vigra::VigraFalseType)
+ AppBase::MultiProgressDisplay & prog)
{
typedef typename SrcAccessor::value_type SrcValueType;
- typedef typename SrcValueType::value_type SrcComponentType;
typedef typename DestAccessor::value_type DestValueType;
- typedef typename DestValueType::value_type DestComponentType;
+ typedef typename AlphaAccessor::value_type AlphaValueType;
+ prog.pushTask(AppBase::ProgressTask("Remapping", "", 0));
+
vigra::Diff2D srcSize = src.second - src.first;
vigra::Diff2D destSize = dest.second - dest.first;
- const int xstart = destUL.x;
- const int xend = destUL.x + destSize.x;
- const int ystart = destUL.y;
- const int yend = destUL.y + destSize.y;
-
- prog.pushTask(AppBase::ProgressTask("Remapping", "", 1.0/(yend-ystart)));
-
vigra_ext::ImageInterpolator<SrcImageIterator, SrcAccessor, Interpolator>
interpol (src, interp, warparound);
@@ -211,91 +154,33 @@
oss << std::setprecision(20) << std::showpoint;
// Emit coordinate transform and interpolator as GLSL shader program.
- oss << "#extension GL_ARB_texture_rectangle : enable" << std::endl
- << "#version 110" << std::endl
- << "uniform sampler2DRect SrcTexture;" << std::endl
- << "vec2 sinc(const in vec2 x) {" << std::endl
- << " vec2 xpi = x * " << M_PI << ";" << std::endl
- << " vec2 result = vec2(1.0, 1.0);" << std::endl
- << " if (xpi.s != 0.0) result.s = sin(xpi.s) / xpi.s;" << std::endl
- << " if (xpi.t != 0.0) result.t = sin(xpi.t) / xpi.t;" << std::endl
- << " return result;" << std::endl
- << "}" << std::endl
- << "float sinh(const in float x) { return (exp(x) - exp(-x)) / 2.0; }" << std::endl
- << "float cosh(const in float x) { return (exp(x) + exp(-x)) / 2.0; }" << std::endl
- << "void main(void)" << std::endl
- << "{" << std::endl;
transform.emitGLSL(oss);
interpol.emitGLSL(oss);
// FIXME need to do response transform
- oss << " gl_FragColor = p;" << std::endl
- << "}" << std::endl;
- float* destBuffer = new float[4 * destSize.x * destSize.y];
- float* srcBuffer = new float[4 * srcSize.x * srcSize.y];
-
- // Copy source image to srcBuffer
- int srcBufferIndex = 0;
- for (SrcImageIterator sy = src.first; sy.y != src.second.y; ++sy.y) {
- for (SrcImageIterator sx = sy; sx.x != src.second.x; ++sx.x) {
- srcBuffer[srcBufferIndex++] = NumericTraits<SrcComponentType>::toRealPromote(src.third(sx).red());
- srcBuffer[srcBufferIndex++] = NumericTraits<SrcComponentType>::toRealPromote(src.third(sx).green());
- srcBuffer[srcBufferIndex++] = NumericTraits<SrcComponentType>::toRealPromote(src.third(sx).blue());
- srcBuffer[srcBufferIndex++] = 1.0f;
- }
- }
-
// Do remapping.
+ // Give the GPU pointers directly to the image data, bypassing the vigra iterators and accessors.
+ // This is cheating. It will not work if the iterators describe subsets of the images or if
+ // the accessors perform computation.
transformImageGPUIntern(oss.str(),
- srcSize.x, srcSize.y,
- srcBuffer,
- xstart, xend,
- ystart, yend,
- destSize.x, destSize.y,
- destBuffer,
+ srcSize,
+ src.first[0],
+ GpuNumericTraits<SrcValueType>::ImagePixelComponentGLType,
+ GpuNumericTraits<SrcValueType>::ImageGLFormat,
+ NULL, /* no alpha buffer */
+ 0,
+ 0,
+ destUL,
+ destSize,
+ dest.first[0],
+ GpuNumericTraits<DestValueType>::ImagePixelComponentGLType,
+ GpuNumericTraits<DestValueType>::ImageGLFormat,
+ alpha.first[0],
+ GpuNumericTraits<AlphaValueType>::ImagePixelComponentGLType,
+ GpuNumericTraits<AlphaValueType>::ImageGLFormat,
warparound);
- // Done with srcBuffer.
- delete[] srcBuffer;
-
- // Copy dest buffer to dest image with pixelTransform.
- DestImageIterator yd(dest.first);
- AlphaImageIterator ydm(alpha.first);
- DestValueType tempval;
-
- int destBufferIndex = 0;
- for(int y=ystart; y < yend; ++y, ++yd.y, ++ydm.y)
- {
- // create x iterators
- DestImageIterator xd(yd);
- AlphaImageIterator xdm(ydm);
- for(int x=xstart; x < xend; ++x, ++xd.x, ++xdm.x)
- {
- tempval.red() = NumericTraits<DestComponentType>::fromRealPromote(destBuffer[destBufferIndex++]);
- tempval.green() = NumericTraits<DestComponentType>::fromRealPromote(destBuffer[destBufferIndex++]);
- tempval.blue() = NumericTraits<DestComponentType>::fromRealPromote(destBuffer[destBufferIndex++]);
- float a = destBuffer[destBufferIndex++];
-
- if (a != 0.0) {
- dest.third.set(tempval, xd);
- //dest.third.set( pixelTransform(tempval, hugin_utils::FDiff2D(0.0, 0.0)), xd);
- alpha.second.set(pixelTransform.hdrWeight(tempval, vigra::UInt8(255)), xdm);
- } else {
- alpha.second.set(0, xdm);
- }
- }
- if (destSize.y > 100) {
- if ((y-ystart)%(destSize.y/20) == 0) {
- prog.setProgress(((double)y-ystart)/destSize.y);
- }
- }
- }
-
- // Done with destBuffer.
- delete[] destBuffer;
-
prog.popTask();
-
}
@@ -316,25 +201,18 @@
vigra::Diff2D destUL,
Interpolator interp,
bool warparound,
- AppBase::MultiProgressDisplay & prog,
- vigra::VigraFalseType)
+ AppBase::MultiProgressDisplay & prog)
{
- typedef typename SrcAlphaAccessor::value_type SrcAlphaType;
typedef typename SrcAccessor::value_type SrcValueType;
- typedef typename SrcValueType::value_type SrcComponentType;
+ typedef typename SrcAlphaAccessor::value_type SrcAlphaType;
typedef typename DestAccessor::value_type DestValueType;
- typedef typename DestValueType::value_type DestComponentType;
+ typedef typename AlphaAccessor::value_type DestAlphaType;
+ prog.pushTask(AppBase::ProgressTask("Remapping", "", 0));
+
vigra::Diff2D srcSize = src.second - src.first;
vigra::Diff2D destSize = dest.second - dest.first;
- const int xstart = destUL.x;
- const int xend = destUL.x + destSize.x;
- const int ystart = destUL.y;
- const int yend = destUL.y + destSize.y;
-
- prog.pushTask(AppBase::ProgressTask("Remapping", "", 1.0/(yend-ystart)));
-
// Note that GPU interpolators are the same for source images with and without alpha channels.
vigra_ext::ImageInterpolator<SrcImageIterator, SrcAccessor, Interpolator>
interpol (src, interp, warparound);
@@ -344,93 +222,32 @@
oss << std::setprecision(20) << std::showpoint;
// Emit coordinate transform and interpolator as GLSL shader program.
- oss << "#extension GL_ARB_texture_rectangle : enable" << endl
- << "#version 110" << std::endl
- << "uniform sampler2DRect SrcTexture;" << std::endl
- << "vec2 sinc(const in vec2 x) {" << std::endl
- << " vec2 xpi = x * " << M_PI << ";" << std::endl
- << " vec2 result = vec2(1.0, 1.0);" << std::endl
- << " if (xpi.s != 0.0) result.s = sin(xpi.s) / xpi.s;" << std::endl
- << " if (xpi.t != 0.0) result.t = sin(xpi.t) / xpi.t;" << std::endl
- << " return result;" << std::endl
- << "}" << std::endl
- << "float sinh(const in float x) { return (exp(x) - exp(-x)) / 2.0; }" << std::endl
- << "float cosh(const in float x) { return (exp(x) + exp(-x)) / 2.0; }" << std::endl
- << "void main(void)" << std::endl
- << "{" << std::endl;
transform.emitGLSL(oss);
interpol.emitGLSL(oss);
// FIXME need to do response transform
- oss << " gl_FragColor = p;" << std::endl
- << "}" << std::endl;
- float* destBuffer = new float[4 * destSize.x * destSize.y];
- float* srcBuffer = new float[4 * srcSize.x * srcSize.y];
-
- // Copy source image to srcBuffer
- int srcBufferIndex = 0;
- SrcAlphaIterator ay = srcAlpha.first;
- for (SrcImageIterator sy = src.first; sy.y != src.second.y; ++sy.y, ++ay.y) {
- SrcAlphaIterator ax = ay;
- for (SrcImageIterator sx = sy; sx.x != src.second.x; ++sx.x, ++ax.x) {
- srcBuffer[srcBufferIndex++] = NumericTraits<SrcComponentType>::toRealPromote(src.third(sx).red());
- srcBuffer[srcBufferIndex++] = NumericTraits<SrcComponentType>::toRealPromote(src.third(sx).green());
- srcBuffer[srcBufferIndex++] = NumericTraits<SrcComponentType>::toRealPromote(src.third(sx).blue());
- srcBuffer[srcBufferIndex++] = NumericTraits<SrcAlphaType>::toRealPromote(srcAlpha.second(ax));
- }
- }
-
// Do remapping.
+ // Give the GPU pointers directly to the image data, bypassing the vigra iterators and accessors.
+ // This is cheating. It will not work if the iterators describe subsets of the images or if
+ // the accessors perform computation.
transformImageGPUIntern(oss.str(),
- srcSize.x, srcSize.y,
- srcBuffer,
- xstart, xend,
- ystart, yend,
- destSize.x, destSize.y,
- destBuffer,
+ srcSize,
+ src.first[0],
+ GpuNumericTraits<SrcValueType>::ImagePixelComponentGLType,
+ GpuNumericTraits<SrcValueType>::ImageGLFormat,
+ srcAlpha.first[0],
+ GpuNumericTraits<SrcAlphaType>::ImagePixelComponentGLType,
+ GpuNumericTraits<SrcAlphaType>::ImageGLFormat,
+ destUL,
+ destSize,
+ dest.first[0],
+ GpuNumericTraits<DestValueType>::ImagePixelComponentGLType,
+ GpuNumericTraits<DestValueType>::ImageGLFormat,
+ alpha.first[0],
+ GpuNumericTraits<DestAlphaType>::ImagePixelComponentGLType,
+ GpuNumericTraits<DestAlphaType>::ImageGLFormat,
warparound);
- // Done with srcBuffer.
- delete[] srcBuffer;
-
- // Copy dest buffer to dest image with pixelTransform.
- DestImageIterator yd(dest.first);
- AlphaImageIterator ydm(alpha.first);
- DestValueType tempval;
- SrcAlphaType alphaval;
-
- int destBufferIndex = 0;
- for(int y=ystart; y < yend; ++y, ++yd.y, ++ydm.y)
- {
- // create x iterators
- DestImageIterator xd(yd);
- AlphaImageIterator xdm(ydm);
- for(int x=xstart; x < xend; ++x, ++xd.x, ++xdm.x)
- {
- tempval.red() = NumericTraits<DestComponentType>::fromRealPromote(destBuffer[destBufferIndex++]);
- tempval.green() = NumericTraits<DestComponentType>::fromRealPromote(destBuffer[destBufferIndex++]);
- tempval.blue() = NumericTraits<DestComponentType>::fromRealPromote(destBuffer[destBufferIndex++]);
- float a = destBuffer[destBufferIndex++];
- alphaval = NumericTraits<SrcAlphaType>::fromRealPromote(a);
-
- if (a != 0.0) {
- dest.third.set(tempval, xd);
- //dest.third.set( pixelTransform(tempval, hugin_utils::FDiff2D(0.0, 0.0)), xd);
- alpha.second.set(pixelTransform.hdrWeight(tempval, alphaval), xdm);
- } else {
- alpha.second.set(0, xdm);
- }
- }
- if (destSize.y > 100) {
- if ((y-ystart)%(destSize.y/20) == 0) {
- prog.setProgress(((double)y-ystart)/destSize.y);
- }
- }
- }
-
- // Done with destBuffer.
- delete[] destBuffer;
-
prog.popTask();
};
@@ -476,54 +293,51 @@
Interpolator interpol,
AppBase::MultiProgressDisplay & progress)
{
- typedef typename SrcAccessor::value_type SrcValueType;
- typedef typename NumericTraits<SrcValueType>::isScalar srcIsScalar;
-
switch (interpol) {
case INTERP_CUBIC:
DEBUG_DEBUG("using cubic interpolator");
transformImageGPUIntern(src, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_cubic(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_SPLINE_16:
DEBUG_DEBUG("interpolator: spline16");
transformImageGPUIntern(src, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_spline16(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_SPLINE_36:
DEBUG_DEBUG("interpolator: spline36");
transformImageGPUIntern(src, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_spline36(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_SPLINE_64:
DEBUG_DEBUG("interpolator: spline64");
transformImageGPUIntern(src, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_spline64(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_SINC_256:
DEBUG_DEBUG("interpolator: sinc 256");
transformImageGPUIntern(src, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_sinc<8>(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_BILINEAR:
transformImageGPUIntern(src, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_bilin(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_NEAREST_NEIGHBOUR:
transformImageGPUIntern(src, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_nearest(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_SINC_1024:
transformImageGPUIntern(src, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_sinc<32>(), warparound,
- progress, srcIsScalar());
+ progress);
break;
}
}
@@ -545,54 +359,51 @@
Interpolator interpol,
AppBase::MultiProgressDisplay & progress)
{
- typedef typename SrcAccessor::value_type SrcValueType;
- typedef typename NumericTraits<SrcValueType>::isScalar srcIsScalar;
-
switch (interpol) {
case INTERP_CUBIC:
DEBUG_DEBUG("using cubic interpolator");
transformImageAlphaGPUIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_cubic(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_SPLINE_16:
DEBUG_DEBUG("interpolator: spline16");
transformImageAlphaGPUIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_spline16(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_SPLINE_36:
DEBUG_DEBUG("interpolator: spline36");
transformImageAlphaGPUIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_spline36(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_SPLINE_64:
DEBUG_DEBUG("interpolator: spline64");
transformImageAlphaGPUIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_spline64(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_SINC_256:
DEBUG_DEBUG("interpolator: sinc 256");
transformImageAlphaGPUIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_sinc<8>(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_BILINEAR:
transformImageAlphaGPUIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_bilin(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_NEAREST_NEIGHBOUR:
transformImageAlphaGPUIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_nearest(), warparound,
- progress, srcIsScalar());
+ progress);
break;
case INTERP_SINC_1024:
transformImageAlphaGPUIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
vigra_ext::interp_sinc<32>(), warparound,
- progress, srcIsScalar());
+ progress);
break;
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|