Commit cda6af19 by Corentin Wallez Committed by Commit Bot

Split pixelBuffer from pack/unpack state

This will refactor will help use packed enums for buffer targets. BUG=angleproject:2169 Change-Id: Ie7ed3e105f89457c67027e6598d7e29503ad355c Reviewed-on: https://chromium-review.googlesource.com/745181 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 29a20992
......@@ -1366,7 +1366,7 @@ Error Framebuffer::readPixels(const gl::Context *context,
ANGLE_TRY(ensureReadAttachmentInitialized(context, GL_COLOR_BUFFER_BIT));
ANGLE_TRY(mImpl->readPixels(context, area, format, type, pixels));
Buffer *unpackBuffer = context->getGLState().getUnpackState().pixelBuffer.get();
Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
if (unpackBuffer)
{
unpackBuffer->onPixelUnpack();
......
......@@ -262,8 +262,8 @@ void State::reset(const Context *context)
mCopyReadBuffer.set(context, nullptr);
mCopyWriteBuffer.set(context, nullptr);
mPack.pixelBuffer.set(context, nullptr);
mUnpack.pixelBuffer.set(context, nullptr);
mPixelPackBuffer.set(context, nullptr);
mPixelUnpackBuffer.set(context, nullptr);
mGenericAtomicCounterBuffer.set(context, nullptr);
for (auto &buf : mAtomicCounterBuffers)
......@@ -1340,13 +1340,13 @@ void State::setCopyWriteBufferBinding(const Context *context, Buffer *buffer)
void State::setPixelPackBufferBinding(const Context *context, Buffer *buffer)
{
mPack.pixelBuffer.set(context, buffer);
mPixelPackBuffer.set(context, buffer);
mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
}
void State::setPixelUnpackBufferBinding(const Context *context, Buffer *buffer)
{
mUnpack.pixelBuffer.set(context, buffer);
mPixelUnpackBuffer.set(context, buffer);
mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
}
......@@ -1358,8 +1358,10 @@ Buffer *State::getTargetBuffer(GLenum target) const
case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
case GL_PIXEL_PACK_BUFFER:
return mPixelPackBuffer.get();
case GL_PIXEL_UNPACK_BUFFER:
return mPixelUnpackBuffer.get();
case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
case GL_ATOMIC_COUNTER_BUFFER:
......@@ -1377,9 +1379,9 @@ Buffer *State::getTargetBuffer(GLenum target) const
void State::detachBuffer(const Context *context, GLuint bufferName)
{
BindingPointer<Buffer> *buffers[] = {
&mArrayBuffer, &mGenericAtomicCounterBuffer, &mCopyReadBuffer,
&mCopyWriteBuffer, &mDrawIndirectBuffer, &mPack.pixelBuffer,
&mUnpack.pixelBuffer, &mGenericUniformBuffer, &mGenericShaderStorageBuffer};
&mArrayBuffer, &mGenericAtomicCounterBuffer, &mCopyReadBuffer,
&mCopyWriteBuffer, &mDrawIndirectBuffer, &mPixelPackBuffer,
&mPixelUnpackBuffer, &mGenericUniformBuffer, &mGenericShaderStorageBuffer};
for (auto buffer : buffers)
{
if (buffer->id() == bufferName)
......@@ -2044,11 +2046,11 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params)
*params = mCopyWriteBuffer.id();
break;
case GL_PIXEL_PACK_BUFFER_BINDING:
*params = mPack.pixelBuffer.id();
break;
*params = mPixelPackBuffer.id();
break;
case GL_PIXEL_UNPACK_BUFFER_BINDING:
*params = mUnpack.pixelBuffer.id();
break;
*params = mPixelUnpackBuffer.id();
break;
case GL_READ_BUFFER:
*params = mReadFramebuffer->getReadBufferState();
break;
......
......@@ -594,7 +594,9 @@ class State : public OnAttachmentDirtyReceiver, angle::NonCopyable
BindingPointer<Buffer> mCopyReadBuffer;
BindingPointer<Buffer> mCopyWriteBuffer;
BindingPointer<Buffer> mPixelUnpackBuffer;
PixelUnpackState mUnpack;
BindingPointer<Buffer> mPixelPackBuffer;
PixelPackState mPack;
bool mPrimitiveRestart;
......
......@@ -57,7 +57,7 @@ InitState DetermineInitState(const Context *context, const uint8_t *pixels)
return InitState::Initialized;
const auto &glState = context->getGLState();
return (pixels == nullptr && glState.getUnpackState().pixelBuffer.get() == nullptr)
return (pixels == nullptr && glState.getTargetBuffer(GL_PIXEL_UNPACK_BUFFER) == nullptr)
? InitState::MayNeedInit
: InitState::Initialized;
}
......
......@@ -259,61 +259,22 @@ struct ImageUnit
GLenum format;
};
struct PixelStoreStateBase : private angle::NonCopyable
struct PixelStoreStateBase
{
BindingPointer<Buffer> pixelBuffer;
GLint alignment = 4;
GLint rowLength = 0;
GLint skipRows = 0;
GLint skipPixels = 0;
GLint imageHeight = 0;
GLint skipImages = 0;
protected:
void copyFrom(const Context *context, const PixelStoreStateBase &other)
{
pixelBuffer.set(context, other.pixelBuffer.get());
alignment = other.alignment;
rowLength = other.rowLength;
skipRows = other.skipRows;
skipPixels = other.skipPixels;
imageHeight = other.imageHeight;
skipImages = other.skipImages;
}
};
struct PixelUnpackState : PixelStoreStateBase
{
PixelUnpackState() {}
PixelUnpackState(GLint alignmentIn, GLint rowLengthIn)
{
alignment = alignmentIn;
rowLength = rowLengthIn;
}
void copyFrom(const Context *context, const PixelUnpackState &other)
{
PixelStoreStateBase::copyFrom(context, other);
}
};
struct PixelPackState : PixelStoreStateBase
{
PixelPackState() {}
PixelPackState(GLint alignmentIn, bool reverseRowOrderIn)
: reverseRowOrder(reverseRowOrderIn)
{
alignment = alignmentIn;
}
void copyFrom(const Context *context, const PixelPackState &other)
{
PixelStoreStateBase::copyFrom(context, other);
reverseRowOrder = other.reverseRowOrder;
}
bool reverseRowOrder = false;
};
......
......@@ -35,19 +35,19 @@ namespace
gl::Error GetUnpackPointer(const gl::Context *context,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels,
ptrdiff_t layerOffset,
const uint8_t **pointerOut)
{
if (unpack.pixelBuffer.id() != 0)
if (unpackBuffer)
{
// Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported
gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
// TODO: this is the only place outside of renderer that asks for a buffers raw data.
// This functionality should be moved into renderer and the getData method of BufferImpl removed.
BufferD3D *bufferD3D = GetImplAs<BufferD3D>(pixelBuffer);
BufferD3D *bufferD3D = GetImplAs<BufferD3D>(unpackBuffer);
ASSERT(bufferD3D);
const uint8_t *bufferData = nullptr;
ANGLE_TRY(bufferD3D->getData(context, &bufferData));
......@@ -216,6 +216,7 @@ gl::Error TextureD3D::setImageImpl(const gl::Context *context,
ptrdiff_t layerOffset)
{
ImageD3D *image = getImage(index);
gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
ASSERT(image);
// No-op
......@@ -227,7 +228,7 @@ gl::Error TextureD3D::setImageImpl(const gl::Context *context,
// We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
// From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
const uint8_t *pixelData = nullptr;
ANGLE_TRY(GetUnpackPointer(context, unpack, pixels, layerOffset, &pixelData));
ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
if (pixelData != nullptr)
{
......@@ -260,7 +261,8 @@ gl::Error TextureD3D::subImage(const gl::Context *context,
{
// CPU readback & copy where direct GPU copy is not supported
const uint8_t *pixelData = nullptr;
ANGLE_TRY(GetUnpackPointer(context, unpack, pixels, layerOffset, &pixelData));
gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
if (pixelData != nullptr)
{
......@@ -297,7 +299,8 @@ gl::Error TextureD3D::setCompressedImageImpl(const gl::Context *context,
// We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
// From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
const uint8_t *pixelData = nullptr;
ANGLE_TRY(GetUnpackPointer(context, unpack, pixels, layerOffset, &pixelData));
gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
if (pixelData != nullptr)
{
......@@ -319,7 +322,8 @@ gl::Error TextureD3D::subImageCompressed(const gl::Context *context,
ptrdiff_t layerOffset)
{
const uint8_t *pixelData = nullptr;
ANGLE_TRY(GetUnpackPointer(context, unpack, pixels, layerOffset, &pixelData));
gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
if (pixelData != nullptr)
{
......@@ -334,9 +338,10 @@ gl::Error TextureD3D::subImageCompressed(const gl::Context *context,
return gl::NoError();
}
bool TextureD3D::isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat)
bool TextureD3D::isFastUnpackable(const gl::Buffer *unpackBuffer, GLenum sizedInternalFormat)
{
return unpack.pixelBuffer.id() != 0 && mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat);
return unpackBuffer != nullptr &&
mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat);
}
gl::Error TextureD3D::fastUnpackPixels(const gl::Context *context,
......@@ -832,7 +837,9 @@ gl::Error TextureD3D_2D::setImage(const gl::Context *context,
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
// Attempt a fast gpu copy of the pixel data to the surface
if (isFastUnpackable(unpack, internalFormatInfo.sizedInternalFormat) && isLevelComplete(level))
gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
if (isFastUnpackable(unpackBuffer, internalFormatInfo.sizedInternalFormat) &&
isLevelComplete(level))
{
// Will try to create RT storage if it does not exist
RenderTargetD3D *destRenderTarget = nullptr;
......@@ -870,7 +877,9 @@ gl::Error TextureD3D_2D::setSubImage(const gl::Context *context,
GLint level = static_cast<GLint>(imageLevel);
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level))
gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
if (isFastUnpackable(unpackBuffer, getInternalFormat(level)) && isLevelComplete(level))
{
RenderTargetD3D *renderTarget = nullptr;
ANGLE_TRY(getRenderTarget(context, index, &renderTarget));
......@@ -954,9 +963,11 @@ gl::Error TextureD3D_2D::copyImage(const gl::Context *context,
angle::MemoryBuffer *zero;
ANGLE_TRY(context->getZeroFilledBuffer(
origSourceArea.width * origSourceArea.height * internalFormatInfo.pixelBytes, &zero));
gl::PixelUnpackState unpack;
unpack.alignment = 1;
ANGLE_TRY(setImage(context, target, imageLevel, internalFormat, sourceExtents,
internalFormatInfo.format, internalFormatInfo.type,
gl::PixelUnpackState(1, 0), zero->data()));
internalFormatInfo.format, internalFormatInfo.type, unpack,
zero->data()));
}
gl::Rectangle sourceArea;
......@@ -1720,9 +1731,11 @@ gl::Error TextureD3D_Cube::copyImage(const gl::Context *context,
angle::MemoryBuffer *zero;
ANGLE_TRY(context->getZeroFilledBuffer(
origSourceArea.width * origSourceArea.height * internalFormatInfo.pixelBytes, &zero));
gl::PixelUnpackState unpack;
unpack.alignment = 1;
ANGLE_TRY(setImage(context, target, imageLevel, internalFormat, size,
internalFormatInfo.format, internalFormatInfo.type,
gl::PixelUnpackState(1, 0), zero->data()));
internalFormatInfo.format, internalFormatInfo.type, unpack,
zero->data()));
}
gl::Rectangle sourceArea;
......@@ -2381,7 +2394,8 @@ gl::Error TextureD3D_3D::setImage(const gl::Context *context,
gl::ImageIndex index = gl::ImageIndex::Make3D(level);
// Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
if (isFastUnpackable(unpack, internalFormatInfo.sizedInternalFormat) && !size.empty() &&
gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
if (isFastUnpackable(unpackBuffer, internalFormatInfo.sizedInternalFormat) && !size.empty() &&
isLevelComplete(level))
{
// Will try to create RT storage if it does not exist
......@@ -2422,7 +2436,8 @@ gl::Error TextureD3D_3D::setSubImage(const gl::Context *context,
gl::ImageIndex index = gl::ImageIndex::Make3D(level);
// Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level))
gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
if (isFastUnpackable(unpackBuffer, getInternalFormat(level)) && isLevelComplete(level))
{
RenderTargetD3D *destRenderTarget = nullptr;
ANGLE_TRY(getRenderTarget(context, index, &destRenderTarget));
......
......@@ -130,7 +130,7 @@ class TextureD3D : public TextureImpl
const gl::PixelUnpackState &unpack,
const uint8_t *pixels,
ptrdiff_t layerOffset);
bool isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat);
bool isFastUnpackable(const gl::Buffer *unpackBuffer, GLenum sizedInternalFormat);
gl::Error fastUnpackPixels(const gl::Context *context,
const gl::PixelUnpackState &unpack,
const uint8_t *pixels,
......
......@@ -1473,7 +1473,7 @@ gl::Error Buffer11::PackStorage::packPixels(const gl::Context *context,
ASSERT(srcTexture.valid());
unsigned int srcSubresource = renderTarget->getSubresourceIndex();
mQueuedPackCommand.reset(new PackPixelsParams(context, params));
mQueuedPackCommand.reset(new PackPixelsParams(params));
gl::Extents srcTextureSize(params.area.width, params.area.height, 1);
if (!mStagingTexture.get() || mStagingTexture.getFormat() != srcTexture.getFormat() ||
......
......@@ -284,12 +284,12 @@ gl::Error Framebuffer11::readPixelsImpl(const gl::Context *context,
const gl::FramebufferAttachment *readAttachment = mState.getReadAttachment();
ASSERT(readAttachment);
gl::Buffer *packBuffer = pack.pixelBuffer.get();
gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_PACK_BUFFER);
if (packBuffer != nullptr)
{
Buffer11 *packBufferStorage = GetImplAs<Buffer11>(packBuffer);
PackPixelsParams packParams(area, format, type, static_cast<GLuint>(outputPitch), pack,
reinterpret_cast<ptrdiff_t>(pixels));
packBuffer, reinterpret_cast<ptrdiff_t>(pixels));
return packBufferStorage->packPixels(context, *readAttachment, packParams);
}
......
......@@ -153,7 +153,7 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::Context *context,
destArea.y >= 0 && destArea.y + destArea.height <= destSize.height &&
destArea.z >= 0 && destArea.z + destArea.depth <= destSize.depth );
const gl::Buffer &sourceBuffer = *unpack.pixelBuffer.get();
const gl::Buffer &sourceBuffer = *context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat));
......
......@@ -3307,25 +3307,24 @@ gl::Error Renderer11::readFromAttachment(const gl::Context *context,
mDeviceContext->CopySubresourceRegion(stagingHelper.get(), 0, 0, 0, 0, srcTexture->get(),
sourceSubResource, &srcBox);
gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_PACK_BUFFER);
if (!invertTexture)
{
PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0);
PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, packBuffer, 0);
return packPixels(stagingHelper, packParams, pixelsOut);
}
gl::PixelPackState invertTexturePack;
// Create a new PixelPackState with reversed row order. Note that we can't just assign
// 'invertTexturePack' to be 'pack' (or memcpy) since that breaks the ref counting/object
// tracking in the 'pixelBuffer' members, causing leaks. Instead we must use
// pixelBuffer.set() twice, which performs the addRef/release correctly
gl::PixelPackState invertTexturePack;
invertTexturePack.alignment = pack.alignment;
invertTexturePack.pixelBuffer.set(context, pack.pixelBuffer.get());
invertTexturePack.reverseRowOrder = !pack.reverseRowOrder;
PackPixelsParams packParams(safeArea, format, type, outputPitch, invertTexturePack, 0);
PackPixelsParams packParams(safeArea, format, type, outputPitch, invertTexturePack, packBuffer,
0);
gl::Error error = packPixels(stagingHelper, packParams, pixelsOut);
invertTexturePack.pixelBuffer.set(context, nullptr);
ANGLE_TRY(error);
return gl::NoError();
}
......
......@@ -85,8 +85,6 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context,
const gl::PixelPackState &pack,
uint8_t *pixels)
{
ASSERT(pack.pixelBuffer.get() == nullptr);
const gl::FramebufferAttachment *colorbuffer = mState.getColorAttachment(0);
ASSERT(colorbuffer);
......@@ -191,7 +189,6 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context,
const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
gl::FormatType formatType(format, type);
// TODO(jmadill): Maybe we can avoid a copy of pack parameters here?
PackPixelsParams packParams;
packParams.area.x = rect.left;
packParams.area.y = rect.top;
......@@ -200,7 +197,7 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context,
packParams.format = format;
packParams.type = type;
packParams.outputPitch = static_cast<GLuint>(outputPitch);
packParams.pack.copyFrom(context, pack);
packParams.pack = pack;
PackPixels(packParams, d3dFormatInfo.info(), inputPitch, source, pixels);
......
......@@ -178,6 +178,8 @@ gl::Error BlitGL::copyImageToLUMAWorkaroundTexture(const gl::Context *context,
gl::PixelUnpackState unpack;
mStateManager->setPixelUnpackState(unpack);
mStateManager->setPixelUnpackBuffer(
context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER));
mFunctions->texImage2D(target, static_cast<GLint>(level), internalFormat, sourceArea.width,
sourceArea.height, 0, format,
source->getImplementationColorReadType(context), nullptr);
......@@ -571,7 +573,10 @@ gl::Error BlitGL::copySubTextureCPUReadback(const gl::Context *context,
readFunction = angle::ReadColor<angle::R8G8B8A8, GLfloat>;
}
mStateManager->setPixelUnpackState(gl::PixelUnpackState(1, 0));
gl::PixelUnpackState unpack;
unpack.alignment = 1;
mStateManager->setPixelUnpackState(unpack);
mStateManager->setPixelUnpackBuffer(nullptr);
mFunctions->readPixels(sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height,
readPixelsFormat, GL_UNSIGNED_BYTE, sourceMemory);
......@@ -585,7 +590,10 @@ gl::Error BlitGL::copySubTextureCPUReadback(const gl::Context *context,
destInternalFormatInfo.componentType, sourceArea.width, sourceArea.height, unpackFlipY,
unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
mStateManager->setPixelPackState(gl::PixelPackState(1, false));
gl::PixelPackState pack;
pack.alignment = 1;
mStateManager->setPixelPackState(pack);
mStateManager->setPixelPackBuffer(nullptr);
nativegl::TexSubImageFormat texSubImageFormat =
nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, destFormat, destType);
......@@ -678,6 +686,7 @@ void BlitGL::orphanScratchTextures()
mStateManager->bindTexture(GL_TEXTURE_2D, texture);
gl::PixelUnpackState unpack;
mStateManager->setPixelUnpackState(unpack);
mStateManager->setPixelUnpackBuffer(nullptr);
mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE,
nullptr);
}
......
......@@ -429,8 +429,8 @@ Error FramebufferGL::readPixels(const gl::Context *context,
return gl::NoError();
}
PixelPackState packState;
packState.copyFrom(context, context->getGLState().getPackState());
PixelPackState packState = context->getGLState().getPackState();
const gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_PACK_BUFFER);
nativegl::ReadPixelsFormat readPixelsFormat =
nativegl::GetReadPixelsFormat(mFunctions, mWorkarounds, format, type);
......@@ -440,7 +440,7 @@ Error FramebufferGL::readPixels(const gl::Context *context,
mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferID);
bool useOverlappingRowsWorkaround = mWorkarounds.packOverlappingRowsSeparatelyPackBuffer &&
packState.pixelBuffer.get() && packState.rowLength != 0 &&
packBuffer && packState.rowLength != 0 &&
packState.rowLength < area.width;
GLubyte *pixels = reinterpret_cast<GLubyte *>(ptrOrOffset);
......@@ -479,9 +479,9 @@ Error FramebufferGL::readPixels(const gl::Context *context,
gl::ErrorOrResult<bool> useLastRowPaddingWorkaround = false;
if (mWorkarounds.packLastRowSeparatelyForPaddingInclusion)
{
useLastRowPaddingWorkaround =
ShouldApplyLastRowPaddingWorkaround(gl::Extents(area.width, area.height, 1),
packState, readFormat, readType, false, pixels);
useLastRowPaddingWorkaround = ShouldApplyLastRowPaddingWorkaround(
gl::Extents(area.width, area.height, 1), packState, packBuffer, readFormat,
readType, false, pixels);
}
if (useLastRowPaddingWorkaround.isError())
......@@ -495,7 +495,6 @@ Error FramebufferGL::readPixels(const gl::Context *context,
}
}
packState.pixelBuffer.set(context, nullptr);
return retVal;
}
......@@ -837,7 +836,6 @@ gl::Error FramebufferGL::readPixelsRowByRow(const gl::Context *context,
const gl::PixelPackState &pack,
GLubyte *pixels) const
{
const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
GLuint rowBytes = 0;
......@@ -847,10 +845,8 @@ gl::Error FramebufferGL::readPixelsRowByRow(const gl::Context *context,
ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, 0, pack, false), skipBytes);
gl::PixelPackState directPack;
directPack.pixelBuffer.set(context, pack.pixelBuffer.get());
directPack.alignment = 1;
mStateManager->setPixelPackState(directPack);
directPack.pixelBuffer.set(context, nullptr);
pixels += skipBytes;
for (GLint y = area.y; y < area.y + area.height; ++y)
......@@ -888,10 +884,8 @@ gl::Error FramebufferGL::readPixelsAllAtOnce(const gl::Context *context,
ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, 0, pack, false), skipBytes);
gl::PixelPackState directPack;
directPack.pixelBuffer.set(context, pack.pixelBuffer.get());
directPack.alignment = 1;
mStateManager->setPixelPackState(directPack);
directPack.pixelBuffer.set(context, nullptr);
pixels += skipBytes + (area.height - 1) * rowBytes;
mFunctions->readPixels(area.x, area.y + area.height - 1, area.width, 1, format, type,
......
......@@ -493,125 +493,108 @@ void StateManagerGL::bindImageTexture(GLuint unit,
void StateManagerGL::setPixelUnpackState(const gl::PixelUnpackState &unpack)
{
GLuint unpackBufferID = 0;
const gl::Buffer *unpackBuffer = unpack.pixelBuffer.get();
if (unpackBuffer != nullptr)
if (mUnpackAlignment != unpack.alignment)
{
unpackBufferID = GetImplAs<BufferGL>(unpackBuffer)->getBufferID();
}
setPixelUnpackState(unpack.alignment, unpack.rowLength, unpack.skipRows, unpack.skipPixels,
unpack.imageHeight, unpack.skipImages, unpackBufferID);
}
void StateManagerGL::setPixelUnpackState(GLint alignment,
GLint rowLength,
GLint skipRows,
GLint skipPixels,
GLint imageHeight,
GLint skipImages,
GLuint unpackBuffer)
{
if (mUnpackAlignment != alignment)
{
mUnpackAlignment = alignment;
mUnpackAlignment = unpack.alignment;
mFunctions->pixelStorei(GL_UNPACK_ALIGNMENT, mUnpackAlignment);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
}
if (mUnpackRowLength != rowLength)
if (mUnpackRowLength != unpack.rowLength)
{
mUnpackRowLength = rowLength;
mUnpackRowLength = unpack.rowLength;
mFunctions->pixelStorei(GL_UNPACK_ROW_LENGTH, mUnpackRowLength);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
}
if (mUnpackSkipRows != skipRows)
if (mUnpackSkipRows != unpack.skipRows)
{
mUnpackSkipRows = skipRows;
mUnpackSkipRows = unpack.skipRows;
mFunctions->pixelStorei(GL_UNPACK_SKIP_ROWS, mUnpackSkipRows);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
}
if (mUnpackSkipPixels != skipPixels)
if (mUnpackSkipPixels != unpack.skipPixels)
{
mUnpackSkipPixels = skipPixels;
mUnpackSkipPixels = unpack.skipPixels;
mFunctions->pixelStorei(GL_UNPACK_SKIP_PIXELS, mUnpackSkipPixels);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
}
if (mUnpackImageHeight != imageHeight)
if (mUnpackImageHeight != unpack.imageHeight)
{
mUnpackImageHeight = imageHeight;
mUnpackImageHeight = unpack.imageHeight;
mFunctions->pixelStorei(GL_UNPACK_IMAGE_HEIGHT, mUnpackImageHeight);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
}
if (mUnpackSkipImages != skipImages)
if (mUnpackSkipImages != unpack.skipImages)
{
mUnpackSkipImages = skipImages;
mUnpackSkipImages = unpack.skipImages;
mFunctions->pixelStorei(GL_UNPACK_SKIP_IMAGES, mUnpackSkipImages);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
}
bindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
}
void StateManagerGL::setPixelPackState(const gl::PixelPackState &pack)
void StateManagerGL::setPixelUnpackBuffer(const gl::Buffer *pixelBuffer)
{
GLuint packBufferID = 0;
const gl::Buffer *packBuffer = pack.pixelBuffer.get();
if (packBuffer != nullptr)
GLuint bufferID = 0;
if (pixelBuffer != nullptr)
{
packBufferID = GetImplAs<BufferGL>(packBuffer)->getBufferID();
bufferID = GetImplAs<BufferGL>(pixelBuffer)->getBufferID();
}
setPixelPackState(pack.alignment, pack.rowLength, pack.skipRows, pack.skipPixels, packBufferID);
bindBuffer(GL_PIXEL_UNPACK_BUFFER, bufferID);
}
void StateManagerGL::setPixelPackState(GLint alignment,
GLint rowLength,
GLint skipRows,
GLint skipPixels,
GLuint packBuffer)
void StateManagerGL::setPixelPackState(const gl::PixelPackState &pack)
{
if (mPackAlignment != alignment)
if (mPackAlignment != pack.alignment)
{
mPackAlignment = alignment;
mPackAlignment = pack.alignment;
mFunctions->pixelStorei(GL_PACK_ALIGNMENT, mPackAlignment);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
}
if (mPackRowLength != rowLength)
if (mPackRowLength != pack.rowLength)
{
mPackRowLength = rowLength;
mPackRowLength = pack.rowLength;
mFunctions->pixelStorei(GL_PACK_ROW_LENGTH, mPackRowLength);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
}
if (mPackSkipRows != skipRows)
if (mPackSkipRows != pack.skipRows)
{
mPackSkipRows = skipRows;
mPackSkipRows = pack.skipRows;
mFunctions->pixelStorei(GL_PACK_SKIP_ROWS, mPackSkipRows);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
}
if (mPackSkipPixels != skipPixels)
if (mPackSkipPixels != pack.skipPixels)
{
mPackSkipPixels = skipPixels;
mPackSkipPixels = pack.skipPixels;
mFunctions->pixelStorei(GL_PACK_SKIP_PIXELS, mPackSkipPixels);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
}
}
bindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
void StateManagerGL::setPixelPackBuffer(const gl::Buffer *pixelBuffer)
{
GLuint bufferID = 0;
if (pixelBuffer != nullptr)
{
bufferID = GetImplAs<BufferGL>(pixelBuffer)->getBufferID();
}
bindBuffer(GL_PIXEL_PACK_BUFFER, bufferID);
}
void StateManagerGL::bindFramebuffer(GLenum type, GLuint framebuffer)
......@@ -1904,13 +1887,13 @@ void StateManagerGL::syncState(const gl::Context *context, const gl::State::Dirt
setPixelUnpackState(state.getUnpackState());
break;
case gl::State::DIRTY_BIT_UNPACK_BUFFER_BINDING:
setPixelUnpackState(state.getUnpackState());
setPixelUnpackBuffer(state.getTargetBuffer(GL_PIXEL_UNPACK_BUFFER));
break;
case gl::State::DIRTY_BIT_PACK_STATE:
setPixelPackState(state.getPackState());
break;
case gl::State::DIRTY_BIT_PACK_BUFFER_BINDING:
setPixelPackState(state.getPackState());
setPixelPackBuffer(state.getTargetBuffer(GL_PIXEL_PACK_BUFFER));
break;
case gl::State::DIRTY_BIT_DITHER_ENABLED:
setDitherEnabled(state.isDitherEnabled());
......
......@@ -128,19 +128,9 @@ class StateManagerGL final : angle::NonCopyable
void setClearStencil(GLint clearStencil);
void setPixelUnpackState(const gl::PixelUnpackState &unpack);
void setPixelUnpackState(GLint alignment,
GLint rowLength,
GLint skipRows,
GLint skipPixels,
GLint imageHeight,
GLint skipImages,
GLuint unpackBuffer);
void setPixelUnpackBuffer(const gl::Buffer *pixelBuffer);
void setPixelPackState(const gl::PixelPackState &pack);
void setPixelPackState(GLint alignment,
GLint rowLength,
GLint skipRows,
GLint skipPixels,
GLuint packBuffer);
void setPixelPackBuffer(const gl::Buffer *pixelBuffer);
void setFramebufferSRGBEnabled(const gl::Context *context, bool enabled);
void setFramebufferSRGBEnabledForFramebuffer(const gl::Context *context,
......
......@@ -172,7 +172,9 @@ gl::Error TextureGL::setImage(const gl::Context *context,
const gl::PixelUnpackState &unpack,
const uint8_t *pixels)
{
if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpack.pixelBuffer.get() &&
const gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpackBuffer &&
unpack.rowLength != 0 && unpack.rowLength < size.width)
{
// The rows overlap in unpack memory. Upload the texture row by row to work around
......@@ -186,15 +188,16 @@ gl::Error TextureGL::setImage(const gl::Context *context,
gl::Box area(0, 0, 0, size.width, size.height, size.depth);
return setSubImageRowByRowWorkaround(context, target, level, area, format, type, unpack,
pixels);
unpackBuffer, pixels);
}
if (mWorkarounds.unpackLastRowSeparatelyForPaddingInclusion)
{
bool apply;
ANGLE_TRY_RESULT(ShouldApplyLastRowPaddingWorkaround(size, unpack, format, type,
UseTexImage3D(getTarget()), pixels),
apply);
ANGLE_TRY_RESULT(
ShouldApplyLastRowPaddingWorkaround(size, unpack, unpackBuffer, format, type,
UseTexImage3D(getTarget()), pixels),
apply);
// The driver will think the pixel buffer doesn't have enough data, work around this bug
// by uploading the last row (and last level if 3D) separately.
......@@ -209,7 +212,7 @@ gl::Error TextureGL::setImage(const gl::Context *context,
gl::Box area(0, 0, 0, size.width, size.height, size.depth);
return setSubImagePaddingWorkaround(context, target, level, area, format, type, unpack,
pixels);
unpackBuffer, pixels);
}
}
......@@ -261,8 +264,7 @@ void TextureGL::reserveTexImageToBeFilled(GLenum target,
GLenum format,
GLenum type)
{
gl::PixelUnpackState unpack;
mStateManager->setPixelUnpackState(unpack);
mStateManager->setPixelUnpackBuffer(nullptr);
setImageHelper(target, level, internalFormat, size, format, type, nullptr);
}
......@@ -276,6 +278,7 @@ gl::Error TextureGL::setSubImage(const gl::Context *context,
const uint8_t *pixels)
{
ASSERT(CompatibleTextureTarget(getTarget(), target));
const gl::Buffer *unpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
nativegl::TexSubImageFormat texSubImageFormat =
nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type);
......@@ -284,11 +287,11 @@ gl::Error TextureGL::setSubImage(const gl::Context *context,
GetLevelInfo(format, texSubImageFormat.format).lumaWorkaround.enabled);
mStateManager->bindTexture(getTarget(), mTextureID);
if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpack.pixelBuffer.get() &&
if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpackBuffer &&
unpack.rowLength != 0 && unpack.rowLength < area.width)
{
return setSubImageRowByRowWorkaround(context, target, level, area, format, type, unpack,
pixels);
unpackBuffer, pixels);
}
if (mWorkarounds.unpackLastRowSeparatelyForPaddingInclusion)
......@@ -296,16 +299,17 @@ gl::Error TextureGL::setSubImage(const gl::Context *context,
gl::Extents size(area.width, area.height, area.depth);
bool apply;
ANGLE_TRY_RESULT(ShouldApplyLastRowPaddingWorkaround(size, unpack, format, type,
UseTexImage3D(getTarget()), pixels),
apply);
ANGLE_TRY_RESULT(
ShouldApplyLastRowPaddingWorkaround(size, unpack, unpackBuffer, format, type,
UseTexImage3D(getTarget()), pixels),
apply);
// The driver will think the pixel buffer doesn't have enough data, work around this bug
// by uploading the last row (and last level if 3D) separately.
if (apply)
{
return setSubImagePaddingWorkaround(context, target, level, area, format, type, unpack,
pixels);
unpackBuffer, pixels);
}
}
......@@ -334,13 +338,13 @@ gl::Error TextureGL::setSubImageRowByRowWorkaround(const gl::Context *context,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
const gl::Buffer *unpackBuffer,
const uint8_t *pixels)
{
gl::PixelUnpackState directUnpack;
directUnpack.pixelBuffer.set(context, unpack.pixelBuffer.get());
directUnpack.alignment = 1;
mStateManager->setPixelUnpackState(directUnpack);
directUnpack.pixelBuffer.set(context, nullptr);
mStateManager->setPixelUnpackBuffer(unpackBuffer);
const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
GLuint rowBytes = 0;
......@@ -391,6 +395,7 @@ gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
const gl::Buffer *unpackBuffer,
const uint8_t *pixels)
{
const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
......@@ -406,9 +411,9 @@ gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context,
skipBytes);
mStateManager->setPixelUnpackState(unpack);
mStateManager->setPixelUnpackBuffer(unpackBuffer);
gl::PixelUnpackState directUnpack;
directUnpack.pixelBuffer.set(context, unpack.pixelBuffer.get());
directUnpack.alignment = 1;
if (useTexImage3D)
......@@ -464,8 +469,6 @@ gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context,
lastRowPixels);
}
directUnpack.pixelBuffer.set(context, nullptr);
return gl::NoError();
}
......@@ -581,7 +584,12 @@ gl::Error TextureGL::copyImage(const gl::Context *context,
angle::MemoryBuffer *zero;
ANGLE_TRY(context->getZeroFilledBuffer(
origSourceArea.width * origSourceArea.height * pixelBytes, &zero));
mStateManager->setPixelUnpackState(gl::PixelUnpackState(1, 0));
gl::PixelUnpackState unpack;
unpack.alignment = 1;
mStateManager->setPixelUnpackState(unpack);
mStateManager->setPixelUnpackBuffer(nullptr);
mFunctions->texImage2D(target, static_cast<GLint>(level), copyTexImageFormat.internalFormat,
origSourceArea.width, origSourceArea.height, 0,
gl::GetUnsizedFormat(copyTexImageFormat.internalFormat), type,
......
......@@ -209,6 +209,7 @@ class TextureGL : public TextureImpl
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
const gl::Buffer *unpackBuffer,
const uint8_t *pixels);
gl::Error setSubImagePaddingWorkaround(const gl::Context *context,
......@@ -218,6 +219,7 @@ class TextureGL : public TextureImpl
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
const gl::Buffer *unpackBuffer,
const uint8_t *pixels);
void syncTextureStateSwizzle(const FunctionsGL *functions,
......
......@@ -1220,12 +1220,13 @@ uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions,
gl::ErrorOrResult<bool> ShouldApplyLastRowPaddingWorkaround(const gl::Extents &size,
const gl::PixelStoreStateBase &state,
const gl::Buffer *pixelBuffer,
GLenum format,
GLenum type,
bool is3D,
const void *pixels)
{
if (state.pixelBuffer.get() == nullptr)
if (pixelBuffer == nullptr)
{
return false;
}
......@@ -1255,7 +1256,7 @@ gl::ErrorOrResult<bool> ShouldApplyLastRowPaddingWorkaround(const gl::Extents &s
ANGLE_TRY_CHECKED_MATH(checkedEndByte);
return checkedEndByte.ValueOrDie() > static_cast<size_t>(state.pixelBuffer->getSize());
return checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelBuffer->getSize());
}
std::vector<ContextCreationTry> GenerateContextCreationToTry(EGLint requestedType, bool isMesaGLX)
......
......@@ -72,6 +72,7 @@ uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions,
gl::ErrorOrResult<bool> ShouldApplyLastRowPaddingWorkaround(const gl::Extents &size,
const gl::PixelStoreStateBase &state,
const gl::Buffer *pixelBuffer,
GLenum format,
GLenum type,
bool is3D,
......
......@@ -119,13 +119,14 @@ gl::Error FramebufferNULL::readPixels(const gl::Context *context,
void *ptrOrOffset)
{
const gl::PixelPackState &packState = context->getGLState().getPackState();
gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_PACK_BUFFER);
// Get the pointer to write to from the argument or the pack buffer
GLubyte *pixels = nullptr;
if (packState.pixelBuffer.get() != nullptr)
if (packBuffer != nullptr)
{
BufferNULL *pixelBuffer = GetImplAs<BufferNULL>(packState.pixelBuffer.get());
pixels = reinterpret_cast<GLubyte *>(pixelBuffer->getDataPtr());
BufferNULL *packBufferGL = GetImplAs<BufferNULL>(packBuffer);
pixels = reinterpret_cast<GLubyte *>(packBufferGL->getDataPtr());
pixels += reinterpret_cast<intptr_t>(ptrOrOffset);
}
else
......
......@@ -237,27 +237,18 @@ PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn,
GLenum typeIn,
GLuint outputPitchIn,
const gl::PixelPackState &packIn,
gl::Buffer *packBufferIn,
ptrdiff_t offsetIn)
: area(areaIn),
format(formatIn),
type(typeIn),
outputPitch(outputPitchIn),
packBuffer(packIn.pixelBuffer.get()),
pack(packIn.alignment, packIn.reverseRowOrder),
offset(offsetIn)
{
}
PackPixelsParams::PackPixelsParams(const gl::Context *context, const PackPixelsParams &other)
: area(other.area),
format(other.format),
type(other.type),
outputPitch(other.outputPitch),
packBuffer(other.packBuffer),
packBuffer(packBufferIn),
pack(),
offset(other.offset)
offset(offsetIn)
{
pack.copyFrom(context, other.pack);
pack.alignment = packIn.alignment;
pack.reverseRowOrder = packIn.reverseRowOrder;
}
void PackPixels(const PackPixelsParams &params,
......@@ -509,7 +500,8 @@ gl::Error IncompleteTextureSet::getIncompleteTexture(
const GLubyte color[] = {0, 0, 0, 255};
const gl::Extents colorSize(1, 1, 1);
const gl::PixelUnpackState unpack(1, 0);
gl::PixelUnpackState unpack;
unpack.alignment = 1;
const gl::Box area(0, 0, 0, 1, 1, 1);
// If a texture is external use a 2D texture for the incomplete texture
......
......@@ -138,7 +138,7 @@ class FastCopyFunctionMap
const Entry *mData;
};
struct PackPixelsParams : private angle::NonCopyable
struct PackPixelsParams
{
PackPixelsParams();
PackPixelsParams(const gl::Rectangle &area,
......@@ -146,8 +146,8 @@ struct PackPixelsParams : private angle::NonCopyable
GLenum type,
GLuint outputPitch,
const gl::PixelPackState &pack,
gl::Buffer *packBufferIn,
ptrdiff_t offset);
PackPixelsParams(const gl::Context *context, const PackPixelsParams &other);
gl::Rectangle area;
GLenum format;
......
......@@ -327,7 +327,8 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
params.format = format;
params.type = type;
params.outputPitch = inputPitch;
params.pack.copyFrom(context, glState.getPackState());
params.packBuffer = glState.getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
params.pack = glState.getPackState();
PackPixels(params, angleFormat, inputPitch, mapPointer, reinterpret_cast<uint8_t *>(pixels));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment