Browse Source

GL: make PixelStorage image height and Z skip work properly on ES3.

Looks like it was never tested, as it asserted on usual usage. Also the
test was doing something completely crazy, that's fixed now as well.
pull/299/head
Vladimír Vondruš 8 years ago
parent
commit
b4c49081c9
  1. 2
      doc/changelog.dox
  2. 46
      src/Magnum/GL/Implementation/RendererState.cpp
  3. 4
      src/Magnum/GL/Implementation/RendererState.h
  4. 41
      src/Magnum/GL/Test/PixelStorageGLTest.cpp

2
doc/changelog.dox

@ -120,6 +120,8 @@ r<Player<T, K>>>)
- Fixed @ref Text::DistanceFieldGlyphCache internal formats on ES2 devices - Fixed @ref Text::DistanceFieldGlyphCache internal formats on ES2 devices
that support @gl_extension{EXT,texture_storage} (see that support @gl_extension{EXT,texture_storage} (see
[mosra/magnum#289](https://github.com/mosra/magnum/pull/289)) [mosra/magnum#289](https://github.com/mosra/magnum/pull/289))
- @ref PixelStorage::imageHeight() and Z value of @ref PixelStorage::skip()
was not properly handled on ES3 / WebGL 2 builds.
@subsection changelog-latest-docs Documentation @subsection changelog-latest-docs Documentation

46
src/Magnum/GL/Implementation/RendererState.cpp

@ -168,14 +168,22 @@ void RendererState::applyPixelStorageInternal(const Magnum::PixelStorage& storag
"GL: non-default PixelStorage::rowLength() is not supported in WebGL 1.0", ); "GL: non-default PixelStorage::rowLength() is not supported in WebGL 1.0", );
#endif #endif
#ifndef MAGNUM_TARGET_GLES /* Image height (not on ES2, on ES3 for unpack only) */
/* Image height (on ES for unpack only, taken care of below) */ #ifndef MAGNUM_TARGET_GLES2
if(state.imageHeight == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.imageHeight != storage.imageHeight()) if(state.imageHeight == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.imageHeight != storage.imageHeight()) {
#ifndef MAGNUM_TARGET_GLES
glPixelStorei(isUnpack ? GL_UNPACK_IMAGE_HEIGHT : GL_PACK_IMAGE_HEIGHT, glPixelStorei(isUnpack ? GL_UNPACK_IMAGE_HEIGHT : GL_PACK_IMAGE_HEIGHT,
state.imageHeight = storage.imageHeight()); state.imageHeight = storage.imageHeight());
#else
if(isUnpack) glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,
state.imageHeight = storage.imageHeight());
else CORRADE_ASSERT(!storage.imageHeight(),
"GL: non-default PixelStorage::imageHeight() for pack is not supported in OpenGL ES", );
#endif
}
#else #else
CORRADE_ASSERT(!storage.imageHeight(), CORRADE_ASSERT(!storage.imageHeight(),
"GL: non-default PixelStorage::imageHeight() is not supported in OpenGL ES", ); "GL: non-default PixelStorage::imageHeight() is not supported in OpenGL ES 2", );
#endif #endif
/* On ES2 done by modifying data pointer */ /* On ES2 done by modifying data pointer */
@ -190,28 +198,18 @@ void RendererState::applyPixelStorageInternal(const Magnum::PixelStorage& storag
glPixelStorei(isUnpack ? GL_UNPACK_SKIP_ROWS : GL_PACK_SKIP_ROWS, glPixelStorei(isUnpack ? GL_UNPACK_SKIP_ROWS : GL_PACK_SKIP_ROWS,
state.skip.y() = storage.skip().y()); state.skip.y() = storage.skip().y());
#ifndef MAGNUM_TARGET_GLES /* Skip images (on ES3 for unpack only) */
/* Skip images (on ES for unpack only, taken care of below) */ if(state.skip.z() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.skip.z() != storage.skip().z()) {
if(state.skip.z() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.skip.z() != storage.skip().z()) #ifndef MAGNUM_TARGET_GLES
glPixelStorei(isUnpack ? GL_UNPACK_SKIP_IMAGES : GL_PACK_SKIP_IMAGES, glPixelStorei(isUnpack ? GL_UNPACK_SKIP_IMAGES : GL_PACK_SKIP_IMAGES,
state.skip.z() = storage.skip().z()); state.skip.z() = storage.skip().z());
#endif #else
#endif if(isUnpack) glPixelStorei(GL_UNPACK_SKIP_IMAGES,
} state.skip.z() = storage.skip().z());
else CORRADE_ASSERT(!storage.skip().z(),
void RendererState::applyPixelStorageUnpack(const Magnum::PixelStorage& storage) { "GL: non-default PixelStorage::skip().z() for pack is not supported in OpenGL ES", );
applyPixelStorageInternal(storage, true); #endif
}
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2)
PixelStorage& state = unpackPixelStorage;
/* Image height (on ES for unpack only) */
if(state.imageHeight == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.imageHeight != storage.imageHeight())
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, state.imageHeight = storage.imageHeight());
/* Skip images (on ES for unpack only) */
if(state.skip.z() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.skip.z() != storage.skip().z())
glPixelStorei(GL_UNPACK_SKIP_IMAGES, state.skip.z() = storage.skip().z());
#endif #endif
} }

4
src/Magnum/GL/Implementation/RendererState.h

@ -83,7 +83,9 @@ struct RendererState {
void applyPixelStoragePack(const Magnum::PixelStorage& storage) { void applyPixelStoragePack(const Magnum::PixelStorage& storage) {
applyPixelStorageInternal(storage, false); applyPixelStorageInternal(storage, false);
} }
void applyPixelStorageUnpack(const Magnum::PixelStorage& storage); void applyPixelStorageUnpack(const Magnum::PixelStorage& storage) {
applyPixelStorageInternal(storage, true);
}
/* Bool parameter is ugly, but this is implementation detail of internal /* Bool parameter is ugly, but this is implementation detail of internal
API so who cares */ API so who cares */

41
src/Magnum/GL/Test/PixelStorageGLTest.cpp

@ -83,16 +83,14 @@ PixelStorageGLTest::PixelStorageGLTest() {
namespace { namespace {
constexpr const char Data2D[] = { constexpr const char Data2D[] = {
/* Skip */ /* Row length ------------------------------------------------------ */ /* Alignment */
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', /* ------------ Skip */ /* Data ------------------------------------ */ /* Alignment */
'\x00', '\x00', '\x00', '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x00',
/* Data */ /* Row length */ /* Alignment */ '\x00', '\x00', '\x00', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x00',
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x00',
'\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x00', '\x00', '\x00', '\x00',
'\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x00', '\x00', '\x00', '\x00'
}; };
constexpr const char ActualData[] = { constexpr const char ActualData[] = {
@ -108,12 +106,11 @@ void PixelStorageGLTest::unpack2D() {
CORRADE_SKIP(Extensions::EXT::unpack_subimage::string() + std::string(" is not supported.")); CORRADE_SKIP(Extensions::EXT::unpack_subimage::string() + std::string(" is not supported."));
#endif #endif
PixelStorage storage; ImageView2D image{PixelStorage{}
storage.setAlignment(2) .setAlignment(2)
.setRowLength(3) .setRowLength(3)
.setSkip({2, 3, 0}); .setSkip({1, 3, 0}),
PixelFormat::RGB, PixelType::UnsignedByte, {2, 3}, Data2D};
ImageView2D image{storage, PixelFormat::RGB, PixelType::UnsignedByte, {2, 3}, Data2D};
Texture2D texture; Texture2D texture;
texture.setStorage(1, TextureFormat::RGB8, {2, 3}) texture.setStorage(1, TextureFormat::RGB8, {2, 3})
@ -158,7 +155,7 @@ void PixelStorageGLTest::pack2D() {
Image2D image{PixelStorage{} Image2D image{PixelStorage{}
.setAlignment(2) .setAlignment(2)
.setRowLength(3) .setRowLength(3)
.setSkip({2, 3, 0}), .setSkip({1, 3, 0}),
PixelFormat::RGB, PixelType::UnsignedByte, {}, Containers::Array<char>{Containers::ValueInit, sizeof(Data2D)}}; PixelFormat::RGB, PixelType::UnsignedByte, {}, Containers::Array<char>{Containers::ValueInit, sizeof(Data2D)}};
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -178,22 +175,20 @@ void PixelStorageGLTest::pack2D() {
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
namespace { namespace {
constexpr const char Data3D[] = { constexpr const char Data3D[] = {
/* Skip */ /* Row length ------------------------------------------------------ */ /* Alignment */
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
/* Row length ------------------------------------------------------ */ /* Alignment */
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', /* ------------ Skip */ /* Data ------------------------------------ */ /* Alignment */
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x00',
'\x00', '\x00', '\x00', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x00',
/* Data */ /* Row length */ /* Alignment */ '\x00', '\x00', '\x00', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x00',
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x00', '\x00', '\x00', '\x00',
'\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x00', '\x00', '\x00', '\x00',
'\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x00', '\x00', '\x00', '\x00',
/* Filling to image height not needed */ /* Filling to image height not needed */
}; };
@ -204,7 +199,7 @@ void PixelStorageGLTest::unpack3D() {
storage.setAlignment(2) storage.setAlignment(2)
.setRowLength(3) .setRowLength(3)
.setImageHeight(5) .setImageHeight(5)
.setSkip({2, 3, 1}); .setSkip({1, 2, 1});
ImageView3D image{storage, PixelFormat::RGB, PixelType::UnsignedByte, {2, 3, 1}, Data3D}; ImageView3D image{storage, PixelFormat::RGB, PixelType::UnsignedByte, {2, 3, 1}, Data3D};
@ -253,7 +248,7 @@ void PixelStorageGLTest::pack3D() {
.setAlignment(2) .setAlignment(2)
.setRowLength(3) .setRowLength(3)
.setImageHeight(5) .setImageHeight(5)
.setSkip({2, 3, 1}), .setSkip({1, 2, 1}),
PixelFormat::RGB, PixelType::UnsignedByte, {}, Containers::Array<char>{Containers::ValueInit, sizeof(Data3D)}}; PixelFormat::RGB, PixelType::UnsignedByte, {}, Containers::Array<char>{Containers::ValueInit, sizeof(Data3D)}};
texture.image(0, image); texture.image(0, image);

Loading…
Cancel
Save