Browse Source

TextureTools: don't query distance field input size if it was passed.

Avoids needless GL calls on each invoication.
pull/674/head
Vladimír Vondruš 1 year ago
parent
commit
665f226025
  1. 30
      src/Magnum/TextureTools/DistanceFieldGL.cpp
  2. 12
      src/Magnum/TextureTools/DistanceFieldGL.h
  3. 50
      src/Magnum/TextureTools/Test/DistanceFieldGLTest.cpp

30
src/Magnum/TextureTools/DistanceFieldGL.cpp

@ -183,15 +183,13 @@ DistanceFieldGL& DistanceFieldGL::operator=(DistanceFieldGL&&) noexcept = defaul
UnsignedInt DistanceFieldGL::radius() const { return _state->radius; }
void DistanceFieldGL::operator()(GL::Texture2D& input, GL::Framebuffer& output, const Range2Di& rectangle, const Vector2i&
#ifdef MAGNUM_TARGET_GLES
imageSize
#endif
) {
void DistanceFieldGL::operator()(GL::Texture2D& input, GL::Framebuffer& output, const Range2Di& rectangle, const Vector2i& imageSize) {
/** @todo Disable depth test, blending and then enable it back (if was previously) */
Vector2i imageSizeToUse = imageSize;
#ifndef MAGNUM_TARGET_GLES
Vector2i imageSize = input.imageSize(0);
if(imageSizeToUse.isZero())
imageSizeToUse = input.imageSize(0);
#endif
CORRADE_ASSERT(output.checkStatus(GL::FramebufferTarget::Draw) == GL::Framebuffer::Status::Complete,
@ -200,9 +198,9 @@ void DistanceFieldGL::operator()(GL::Texture2D& input, GL::Framebuffer& output,
/* The shader assumes that the ratio between the output and input is a
multiple of 2, causing output pixel *centers* to be aligned with input
pixel *edges* */
CORRADE_ASSERT(imageSize % rectangle.size() == Vector2i{0} &&
(imageSize/rectangle.size()) % 2 == Vector2i{0},
"TextureTools::DistanceFieldGL: expected input and output size ratio to be a multiple of 2, got" << Debug::packed << imageSize << "and" << Debug::packed << rectangle.size(), );
CORRADE_ASSERT(imageSizeToUse % rectangle.size() == Vector2i{0} &&
(imageSizeToUse/rectangle.size()) % 2 == Vector2i{0},
"TextureTools::DistanceFieldGL: expected input and output size ratio to be a multiple of 2, got" << Debug::packed << imageSizeToUse << "and" << Debug::packed << rectangle.size(), );
/* Save existing viewport to restore it back after */
const Range2Di previousViewport = output.viewport();
@ -213,7 +211,7 @@ void DistanceFieldGL::operator()(GL::Texture2D& input, GL::Framebuffer& output,
_state->shader
.bindTexture(input)
.setImageSizeInverted(1.0f/Vector2(imageSize))
.setImageSizeInverted(1.0f/Vector2{imageSizeToUse})
.draw(_state->mesh);
/* Restore the previous viewport */
@ -226,19 +224,11 @@ void DistanceFieldGL::operator()(GL::Texture2D& input, GL::Framebuffer& output,
}
#endif
void DistanceFieldGL::operator()(GL::Texture2D& input, GL::Texture2D& output, const Range2Di& rectangle, const Vector2i&
#ifdef MAGNUM_TARGET_GLES
imageSize
#endif
) {
void DistanceFieldGL::operator()(GL::Texture2D& input, GL::Texture2D& output, const Range2Di& rectangle, const Vector2i& imageSize) {
GL::Framebuffer framebuffer{rectangle};
framebuffer.attachTexture(GL::Framebuffer::ColorAttachment(0), output, 0);
operator()(input, framebuffer, rectangle
#ifdef MAGNUM_TARGET_GLES
, imageSize
#endif
);
operator()(input, framebuffer, rectangle, imageSize);
}
#ifndef MAGNUM_TARGET_GLES

12
src/Magnum/TextureTools/DistanceFieldGL.h

@ -231,9 +231,9 @@ class MAGNUM_TEXTURETOOLS_EXPORT DistanceFieldGL {
* @param input Input texture
* @param output Output framebuffer
* @param rectangle Rectangle in the output where to render
* @param imageSize Input texture size. Needed only for OpenGL ES,
* on desktop GL the size is queried automatically using
* @ref GL::Texture2D::imageSize() and this parameter is ignored.
* @param imageSize Input texture size. Mandatory on OpenGL ES and
* WebGL, on desktop GL if left at default the size is internally
* queried using @ref GL::Texture2D::imageSize() instead.
* @m_since_latest
*
* The @p output texture is expected to have a framebuffer-drawable
@ -274,9 +274,9 @@ class MAGNUM_TEXTURETOOLS_EXPORT DistanceFieldGL {
* @param input Input texture
* @param output Output texture
* @param rectangle Rectangle in the output where to render
* @param imageSize Input texture size. Needed only for OpenGL ES,
* on desktop GL the information is gathered automatically using
* @ref GL::Texture2D::imageSize().
* @param imageSize Input texture size. Mandatory on OpenGL ES and
* WebGL, on desktop GL if left at default the size is internally
* queried using @ref GL::Texture2D::imageSize() instead.
*
* Convenience variant of @ref operator()(GL::Texture2D&, GL::Framebuffer&, const Range2Di&, const Vector2i&)
* that creates a temporary framebuffer with @p output attached and

50
src/Magnum/TextureTools/Test/DistanceFieldGLTest.cpp

@ -81,27 +81,35 @@ using namespace Math::Literals;
const struct {
const char* name;
bool framebuffer;
bool framebuffer, implicitOutputSize;
Vector2i size;
Vector2i offset;
bool flipX, flipY;
} RunData[]{
{"texture output",
false, {64, 64}, {}, false, false},
false, false, {64, 64}, {}, false, false},
{"texture output, flipped on X",
false, {64, 64}, {}, true, false},
false, false, {64, 64}, {}, true, false},
{"texture output, flipped on Y",
false, {64, 64}, {}, false, true},
false, false, {64, 64}, {}, false, true},
{"texture output, with offset",
false, {128, 96}, {64, 32}, false, false},
false, false, {128, 96}, {64, 32}, false, false},
#ifndef MAGNUM_TARGET_GLES
{"texture output with implicit size",
false, true, {64, 64}, {}, false, false},
#endif
{"framebuffer output",
true, {64, 64}, {}, false, false},
true, false, {64, 64}, {}, false, false},
{"framebuffer output, flipped on X",
true, {64, 64}, {}, true, false},
true, false, {64, 64}, {}, true, false},
{"framebuffer output, flipped on Y",
true, {64, 64}, {}, false, true},
true, false, {64, 64}, {}, false, true},
{"framebuffer output, with offset",
true, {128, 96}, {64, 32}, false, false},
true, false, {128, 96}, {64, 32}, false, false},
#ifndef MAGNUM_TARGET_GLES
{"framebuffer output with implicit size",
true, true, {64, 64}, {}, false, false},
#endif
};
#ifndef MAGNUM_TARGET_WEBGL
@ -279,17 +287,25 @@ void DistanceFieldGLTest::run() {
MAGNUM_VERIFY_NO_GL_ERROR();
if(data.framebuffer) {
distanceField(input, outputFramebuffer, Range2Di::fromSize(data.offset, Vector2i{64})
#ifdef MAGNUM_TARGET_GLES
, inputImage->size()
#ifndef MAGNUM_TARGET_GLES
if(data.implicitOutputSize)
distanceField(input, outputFramebuffer,
Range2Di::fromSize(data.offset, Vector2i{64}));
else
#endif
);
distanceField(input, outputFramebuffer,
Range2Di::fromSize(data.offset, Vector2i{64}),
inputImage->size());
} else {
distanceField(input, outputTexture, Range2Di::fromSize(data.offset, Vector2i{64})
#ifdef MAGNUM_TARGET_GLES
, inputImage->size()
#ifndef MAGNUM_TARGET_GLES
if(data.implicitOutputSize)
distanceField(input, outputTexture,
Range2Di::fromSize(data.offset, Vector2i{64}));
else
#endif
);
distanceField(input, outputTexture,
Range2Di::fromSize(data.offset, Vector2i{64}),
inputImage->size());
}
/* The viewport should stay as it was before */

Loading…
Cancel
Save