Commit 2cb7f974 by Geoff Lang Committed by Commit Bot

GL: Refactor TextureGL to not hold renderer objects.

BUG=angleproject:2464 Change-Id: I24b07557d90988369bc8b7e4b2fe3a500ab7bc36 Reviewed-on: https://chromium-review.googlesource.com/1048115Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 8073a951
...@@ -138,7 +138,7 @@ Error Surface::destroyImpl(const Display *display) ...@@ -138,7 +138,7 @@ Error Surface::destroyImpl(const Display *display)
{ {
return Error(EGL_BAD_SURFACE); return Error(EGL_BAD_SURFACE);
} }
mTexture.set(nullptr, nullptr); mTexture.set(display->getProxyContext(), nullptr);
} }
if (mState.defaultFramebuffer) if (mState.defaultFramebuffer)
......
...@@ -523,10 +523,10 @@ gl::ErrorOrResult<bool> BlitGL::copySubTexture(const gl::Context *context, ...@@ -523,10 +523,10 @@ gl::ErrorOrResult<bool> BlitGL::copySubTexture(const gl::Context *context,
} }
GLint swizzle[4] = {luminance, luminance, luminance, alpha}; GLint swizzle[4] = {luminance, luminance, luminance, alpha};
source->setSwizzle(swizzle); source->setSwizzle(context, swizzle);
} }
source->setMinFilter(GL_NEAREST); source->setMinFilter(context, GL_NEAREST);
source->setMagFilter(GL_NEAREST); source->setMagFilter(context, GL_NEAREST);
ANGLE_TRY(source->setBaseLevel(context, static_cast<GLuint>(sourceLevel))); ANGLE_TRY(source->setBaseLevel(context, static_cast<GLuint>(sourceLevel)));
// Render to the destination texture, sampling from the source texture // Render to the destination texture, sampling from the source texture
......
...@@ -75,8 +75,14 @@ FramebufferImpl *ContextGL::createFramebuffer(const gl::FramebufferState &data) ...@@ -75,8 +75,14 @@ FramebufferImpl *ContextGL::createFramebuffer(const gl::FramebufferState &data)
TextureImpl *ContextGL::createTexture(const gl::TextureState &state) TextureImpl *ContextGL::createTexture(const gl::TextureState &state)
{ {
return new TextureGL(state, getFunctions(), getWorkaroundsGL(), getStateManager(), const FunctionsGL *functions = getFunctions();
mRenderer->getBlitter()); StateManagerGL *stateManager = getStateManager();
GLuint texture = 0;
functions->genTextures(1, &texture);
stateManager->bindTexture(state.getType(), texture);
return new TextureGL(state, texture);
} }
RenderbufferImpl *ContextGL::createRenderbuffer(const gl::RenderbufferState &state) RenderbufferImpl *ContextGL::createRenderbuffer(const gl::RenderbufferState &state)
......
...@@ -107,37 +107,29 @@ LevelInfoGL::LevelInfoGL(GLenum sourceFormat_, ...@@ -107,37 +107,29 @@ LevelInfoGL::LevelInfoGL(GLenum sourceFormat_,
{ {
} }
TextureGL::TextureGL(const gl::TextureState &state, TextureGL::TextureGL(const gl::TextureState &state, GLuint id)
const FunctionsGL *functions,
const WorkaroundsGL &workarounds,
StateManagerGL *stateManager,
BlitGL *blitter)
: TextureImpl(state), : TextureImpl(state),
mFunctions(functions),
mWorkarounds(workarounds),
mStateManager(stateManager),
mBlitter(blitter),
mLevelInfo(),
mAppliedSwizzle(state.getSwizzleState()), mAppliedSwizzle(state.getSwizzleState()),
mAppliedSampler(state.getSamplerState()), mAppliedSampler(state.getSamplerState()),
mAppliedBaseLevel(state.getEffectiveBaseLevel()), mAppliedBaseLevel(state.getEffectiveBaseLevel()),
mAppliedMaxLevel(state.getEffectiveMaxLevel()), mAppliedMaxLevel(state.getEffectiveMaxLevel()),
mTextureID(0) mTextureID(id)
{ {
ASSERT(mFunctions);
ASSERT(mStateManager);
ASSERT(mBlitter);
mFunctions->genTextures(1, &mTextureID);
mStateManager->bindTexture(getType(), mTextureID);
mLevelInfo.resize((gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) * mLevelInfo.resize((gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) *
(getType() == gl::TextureType::CubeMap ? 6 : 1)); (getType() == gl::TextureType::CubeMap ? 6 : 1));
} }
TextureGL::~TextureGL() TextureGL::~TextureGL()
{ {
mStateManager->deleteTexture(mTextureID); ASSERT(mTextureID == 0);
}
gl::Error TextureGL::onDestroy(const gl::Context *context)
{
StateManagerGL *stateManager = GetStateManagerGL(context);
stateManager->deleteTexture(mTextureID);
mTextureID = 0; mTextureID = 0;
return gl::NoError();
} }
gl::Error TextureGL::setImage(const gl::Context *context, gl::Error TextureGL::setImage(const gl::Context *context,
...@@ -149,18 +141,20 @@ gl::Error TextureGL::setImage(const gl::Context *context, ...@@ -149,18 +141,20 @@ gl::Error TextureGL::setImage(const gl::Context *context,
const gl::PixelUnpackState &unpack, const gl::PixelUnpackState &unpack,
const uint8_t *pixels) const uint8_t *pixels)
{ {
const WorkaroundsGL &workarounds = GetWorkaroundsGL(context);
const gl::Buffer *unpackBuffer = const gl::Buffer *unpackBuffer =
context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
gl::TextureTarget target = index.getTarget(); gl::TextureTarget target = index.getTarget();
size_t level = static_cast<size_t>(index.getLevelIndex()); size_t level = static_cast<size_t>(index.getLevelIndex());
if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpackBuffer && if (workarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpackBuffer &&
unpack.rowLength != 0 && unpack.rowLength < size.width) unpack.rowLength != 0 && unpack.rowLength < size.width)
{ {
// The rows overlap in unpack memory. Upload the texture row by row to work around // The rows overlap in unpack memory. Upload the texture row by row to work around
// driver bug. // driver bug.
reserveTexImageToBeFilled(target, level, internalFormat, size, format, type); reserveTexImageToBeFilled(context, target, level, internalFormat, size, format, type);
if (size.width == 0 || size.height == 0 || size.depth == 0) if (size.width == 0 || size.height == 0 || size.depth == 0)
{ {
...@@ -172,7 +166,7 @@ gl::Error TextureGL::setImage(const gl::Context *context, ...@@ -172,7 +166,7 @@ gl::Error TextureGL::setImage(const gl::Context *context,
unpackBuffer, pixels); unpackBuffer, pixels);
} }
if (mWorkarounds.unpackLastRowSeparatelyForPaddingInclusion) if (workarounds.unpackLastRowSeparatelyForPaddingInclusion)
{ {
bool apply; bool apply;
ANGLE_TRY_RESULT( ANGLE_TRY_RESULT(
...@@ -184,7 +178,7 @@ gl::Error TextureGL::setImage(const gl::Context *context, ...@@ -184,7 +178,7 @@ gl::Error TextureGL::setImage(const gl::Context *context,
// by uploading the last row (and last level if 3D) separately. // by uploading the last row (and last level if 3D) separately.
if (apply) if (apply)
{ {
reserveTexImageToBeFilled(target, level, internalFormat, size, format, type); reserveTexImageToBeFilled(context, target, level, internalFormat, size, format, type);
if (size.width == 0 || size.height == 0 || size.depth == 0) if (size.width == 0 || size.height == 0 || size.depth == 0)
{ {
...@@ -197,12 +191,13 @@ gl::Error TextureGL::setImage(const gl::Context *context, ...@@ -197,12 +191,13 @@ gl::Error TextureGL::setImage(const gl::Context *context,
} }
} }
setImageHelper(target, level, internalFormat, size, format, type, pixels); setImageHelper(context, target, level, internalFormat, size, format, type, pixels);
return gl::NoError(); return gl::NoError();
} }
void TextureGL::setImageHelper(gl::TextureTarget target, void TextureGL::setImageHelper(const gl::Context *context,
gl::TextureTarget target,
size_t level, size_t level,
GLenum internalFormat, GLenum internalFormat,
const gl::Extents &size, const gl::Extents &size,
...@@ -212,23 +207,27 @@ void TextureGL::setImageHelper(gl::TextureTarget target, ...@@ -212,23 +207,27 @@ void TextureGL::setImageHelper(gl::TextureTarget target,
{ {
ASSERT(TextureTargetToType(target) == getType()); ASSERT(TextureTargetToType(target) == getType());
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const WorkaroundsGL &workarounds = GetWorkaroundsGL(context);
nativegl::TexImageFormat texImageFormat = nativegl::TexImageFormat texImageFormat =
nativegl::GetTexImageFormat(mFunctions, mWorkarounds, internalFormat, format, type); nativegl::GetTexImageFormat(functions, workarounds, internalFormat, format, type);
mStateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
if (nativegl::UseTexImage2D(getType())) if (nativegl::UseTexImage2D(getType()))
{ {
ASSERT(size.depth == 1); ASSERT(size.depth == 1);
mFunctions->texImage2D(ToGLenum(target), static_cast<GLint>(level), functions->texImage2D(ToGLenum(target), static_cast<GLint>(level),
texImageFormat.internalFormat, size.width, size.height, 0, texImageFormat.internalFormat, size.width, size.height, 0,
texImageFormat.format, texImageFormat.type, pixels); texImageFormat.format, texImageFormat.type, pixels);
} }
else if (nativegl::UseTexImage3D(getType())) else if (nativegl::UseTexImage3D(getType()))
{ {
mFunctions->texImage3D(ToGLenum(target), static_cast<GLint>(level), functions->texImage3D(ToGLenum(target), static_cast<GLint>(level),
texImageFormat.internalFormat, size.width, size.height, size.depth, texImageFormat.internalFormat, size.width, size.height, size.depth, 0,
0, texImageFormat.format, texImageFormat.type, pixels); texImageFormat.format, texImageFormat.type, pixels);
} }
else else
{ {
...@@ -238,15 +237,17 @@ void TextureGL::setImageHelper(gl::TextureTarget target, ...@@ -238,15 +237,17 @@ void TextureGL::setImageHelper(gl::TextureTarget target,
setLevelInfo(target, level, 1, GetLevelInfo(internalFormat, texImageFormat.internalFormat)); setLevelInfo(target, level, 1, GetLevelInfo(internalFormat, texImageFormat.internalFormat));
} }
void TextureGL::reserveTexImageToBeFilled(gl::TextureTarget target, void TextureGL::reserveTexImageToBeFilled(const gl::Context *context,
gl::TextureTarget target,
size_t level, size_t level,
GLenum internalFormat, GLenum internalFormat,
const gl::Extents &size, const gl::Extents &size,
GLenum format, GLenum format,
GLenum type) GLenum type)
{ {
mStateManager->setPixelUnpackBuffer(nullptr); StateManagerGL *stateManager = GetStateManagerGL(context);
setImageHelper(target, level, internalFormat, size, format, type, nullptr); stateManager->setPixelUnpackBuffer(nullptr);
setImageHelper(context, target, level, internalFormat, size, format, type, nullptr);
} }
gl::Error TextureGL::setSubImage(const gl::Context *context, gl::Error TextureGL::setSubImage(const gl::Context *context,
...@@ -259,11 +260,15 @@ gl::Error TextureGL::setSubImage(const gl::Context *context, ...@@ -259,11 +260,15 @@ gl::Error TextureGL::setSubImage(const gl::Context *context,
{ {
ASSERT(TextureTargetToType(index.getTarget()) == getType()); ASSERT(TextureTargetToType(index.getTarget()) == getType());
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const WorkaroundsGL &workarounds = GetWorkaroundsGL(context);
const gl::Buffer *unpackBuffer = const gl::Buffer *unpackBuffer =
context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
nativegl::TexSubImageFormat texSubImageFormat = nativegl::TexSubImageFormat texSubImageFormat =
nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type); nativegl::GetTexSubImageFormat(functions, workarounds, format, type);
gl::TextureTarget target = index.getTarget(); gl::TextureTarget target = index.getTarget();
size_t level = static_cast<size_t>(index.getLevelIndex()); size_t level = static_cast<size_t>(index.getLevelIndex());
...@@ -271,15 +276,15 @@ gl::Error TextureGL::setSubImage(const gl::Context *context, ...@@ -271,15 +276,15 @@ gl::Error TextureGL::setSubImage(const gl::Context *context,
ASSERT(getLevelInfo(target, level).lumaWorkaround.enabled == ASSERT(getLevelInfo(target, level).lumaWorkaround.enabled ==
GetLevelInfo(format, texSubImageFormat.format).lumaWorkaround.enabled); GetLevelInfo(format, texSubImageFormat.format).lumaWorkaround.enabled);
mStateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpackBuffer && if (workarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpackBuffer &&
unpack.rowLength != 0 && unpack.rowLength < area.width) unpack.rowLength != 0 && unpack.rowLength < area.width)
{ {
return setSubImageRowByRowWorkaround(context, target, level, area, format, type, unpack, return setSubImageRowByRowWorkaround(context, target, level, area, format, type, unpack,
unpackBuffer, pixels); unpackBuffer, pixels);
} }
if (mWorkarounds.unpackLastRowSeparatelyForPaddingInclusion) if (workarounds.unpackLastRowSeparatelyForPaddingInclusion)
{ {
gl::Extents size(area.width, area.height, area.depth); gl::Extents size(area.width, area.height, area.depth);
...@@ -301,14 +306,14 @@ gl::Error TextureGL::setSubImage(const gl::Context *context, ...@@ -301,14 +306,14 @@ gl::Error TextureGL::setSubImage(const gl::Context *context,
if (nativegl::UseTexImage2D(getType())) if (nativegl::UseTexImage2D(getType()))
{ {
ASSERT(area.z == 0 && area.depth == 1); ASSERT(area.z == 0 && area.depth == 1);
mFunctions->texSubImage2D(ToGLenum(target), static_cast<GLint>(level), area.x, area.y, functions->texSubImage2D(ToGLenum(target), static_cast<GLint>(level), area.x, area.y,
area.width, area.height, texSubImageFormat.format, area.width, area.height, texSubImageFormat.format,
texSubImageFormat.type, pixels); texSubImageFormat.type, pixels);
} }
else else
{ {
ASSERT(nativegl::UseTexImage3D(getType())); ASSERT(nativegl::UseTexImage3D(getType()));
mFunctions->texSubImage3D(ToGLenum(target), static_cast<GLint>(level), area.x, area.y, functions->texSubImage3D(ToGLenum(target), static_cast<GLint>(level), area.x, area.y,
area.z, area.width, area.height, area.depth, area.z, area.width, area.height, area.depth,
texSubImageFormat.format, texSubImageFormat.type, pixels); texSubImageFormat.format, texSubImageFormat.type, pixels);
} }
...@@ -326,10 +331,13 @@ gl::Error TextureGL::setSubImageRowByRowWorkaround(const gl::Context *context, ...@@ -326,10 +331,13 @@ gl::Error TextureGL::setSubImageRowByRowWorkaround(const gl::Context *context,
const gl::Buffer *unpackBuffer, const gl::Buffer *unpackBuffer,
const uint8_t *pixels) const uint8_t *pixels)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
gl::PixelUnpackState directUnpack; gl::PixelUnpackState directUnpack;
directUnpack.alignment = 1; directUnpack.alignment = 1;
mStateManager->setPixelUnpackState(directUnpack); stateManager->setPixelUnpackState(directUnpack);
mStateManager->setPixelUnpackBuffer(unpackBuffer); stateManager->setPixelUnpackBuffer(unpackBuffer);
const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type); const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
GLuint rowBytes = 0; GLuint rowBytes = 0;
...@@ -354,7 +362,7 @@ gl::Error TextureGL::setSubImageRowByRowWorkaround(const gl::Context *context, ...@@ -354,7 +362,7 @@ gl::Error TextureGL::setSubImageRowByRowWorkaround(const gl::Context *context,
{ {
GLint byteOffset = imageByteOffset + row * rowBytes; GLint byteOffset = imageByteOffset + row * rowBytes;
const GLubyte *rowPixels = pixelsWithSkip + byteOffset; const GLubyte *rowPixels = pixelsWithSkip + byteOffset;
mFunctions->texSubImage3D(ToGLenum(target), static_cast<GLint>(level), area.x, functions->texSubImage3D(ToGLenum(target), static_cast<GLint>(level), area.x,
row + area.y, image + area.z, area.width, 1, 1, format, row + area.y, image + area.z, area.width, 1, 1, format,
type, rowPixels); type, rowPixels);
} }
...@@ -367,7 +375,7 @@ gl::Error TextureGL::setSubImageRowByRowWorkaround(const gl::Context *context, ...@@ -367,7 +375,7 @@ gl::Error TextureGL::setSubImageRowByRowWorkaround(const gl::Context *context,
{ {
GLint byteOffset = row * rowBytes; GLint byteOffset = row * rowBytes;
const GLubyte *rowPixels = pixelsWithSkip + byteOffset; const GLubyte *rowPixels = pixelsWithSkip + byteOffset;
mFunctions->texSubImage2D(ToGLenum(target), static_cast<GLint>(level), area.x, functions->texSubImage2D(ToGLenum(target), static_cast<GLint>(level), area.x,
row + area.y, area.width, 1, format, type, rowPixels); row + area.y, area.width, 1, format, type, rowPixels);
} }
} }
...@@ -384,6 +392,9 @@ gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context, ...@@ -384,6 +392,9 @@ gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context,
const gl::Buffer *unpackBuffer, const gl::Buffer *unpackBuffer,
const uint8_t *pixels) const uint8_t *pixels)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type); const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
GLuint rowBytes = 0; GLuint rowBytes = 0;
ANGLE_TRY_RESULT(glFormat.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength), ANGLE_TRY_RESULT(glFormat.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength),
...@@ -396,8 +407,8 @@ gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context, ...@@ -396,8 +407,8 @@ gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context,
ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, imageBytes, unpack, useTexImage3D), ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, imageBytes, unpack, useTexImage3D),
skipBytes); skipBytes);
mStateManager->setPixelUnpackState(unpack); stateManager->setPixelUnpackState(unpack);
mStateManager->setPixelUnpackBuffer(unpackBuffer); stateManager->setPixelUnpackBuffer(unpackBuffer);
gl::PixelUnpackState directUnpack; gl::PixelUnpackState directUnpack;
directUnpack.alignment = 1; directUnpack.alignment = 1;
...@@ -407,7 +418,7 @@ gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context, ...@@ -407,7 +418,7 @@ gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context,
// Upload all but the last slice // Upload all but the last slice
if (area.depth > 1) if (area.depth > 1)
{ {
mFunctions->texSubImage3D(ToGLenum(target), static_cast<GLint>(level), area.x, area.y, functions->texSubImage3D(ToGLenum(target), static_cast<GLint>(level), area.x, area.y,
area.z, area.width, area.height, area.depth - 1, format, type, area.z, area.width, area.height, area.depth - 1, format, type,
pixels); pixels);
} }
...@@ -419,18 +430,18 @@ gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context, ...@@ -419,18 +430,18 @@ gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context,
// the driver // the driver
GLint lastImageOffset = (area.depth - 1) * imageBytes; GLint lastImageOffset = (area.depth - 1) * imageBytes;
const GLubyte *lastImagePixels = pixels + lastImageOffset; const GLubyte *lastImagePixels = pixels + lastImageOffset;
mFunctions->texSubImage3D(ToGLenum(target), static_cast<GLint>(level), area.x, area.y, functions->texSubImage3D(ToGLenum(target), static_cast<GLint>(level), area.x, area.y,
area.z + area.depth - 1, area.width, area.height - 1, 1, area.z + area.depth - 1, area.width, area.height - 1, 1,
format, type, lastImagePixels); format, type, lastImagePixels);
} }
// Upload the last row of the last slice "manually" // Upload the last row of the last slice "manually"
mStateManager->setPixelUnpackState(directUnpack); stateManager->setPixelUnpackState(directUnpack);
GLint lastRowOffset = GLint lastRowOffset =
skipBytes + (area.depth - 1) * imageBytes + (area.height - 1) * rowBytes; skipBytes + (area.depth - 1) * imageBytes + (area.height - 1) * rowBytes;
const GLubyte *lastRowPixels = pixels + lastRowOffset; const GLubyte *lastRowPixels = pixels + lastRowOffset;
mFunctions->texSubImage3D(ToGLenum(target), static_cast<GLint>(level), area.x, functions->texSubImage3D(ToGLenum(target), static_cast<GLint>(level), area.x,
area.y + area.height - 1, area.z + area.depth - 1, area.width, 1, area.y + area.height - 1, area.z + area.depth - 1, area.width, 1,
1, format, type, lastRowPixels); 1, format, type, lastRowPixels);
} }
...@@ -441,16 +452,16 @@ gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context, ...@@ -441,16 +452,16 @@ gl::Error TextureGL::setSubImagePaddingWorkaround(const gl::Context *context,
// Upload all but the last row // Upload all but the last row
if (area.height > 1) if (area.height > 1)
{ {
mFunctions->texSubImage2D(ToGLenum(target), static_cast<GLint>(level), area.x, area.y, functions->texSubImage2D(ToGLenum(target), static_cast<GLint>(level), area.x, area.y,
area.width, area.height - 1, format, type, pixels); area.width, area.height - 1, format, type, pixels);
} }
// Upload the last row "manually" // Upload the last row "manually"
mStateManager->setPixelUnpackState(directUnpack); stateManager->setPixelUnpackState(directUnpack);
GLint lastRowOffset = skipBytes + (area.height - 1) * rowBytes; GLint lastRowOffset = skipBytes + (area.height - 1) * rowBytes;
const GLubyte *lastRowPixels = pixels + lastRowOffset; const GLubyte *lastRowPixels = pixels + lastRowOffset;
mFunctions->texSubImage2D(ToGLenum(target), static_cast<GLint>(level), area.x, functions->texSubImage2D(ToGLenum(target), static_cast<GLint>(level), area.x,
area.y + area.height - 1, area.width, 1, format, type, area.y + area.height - 1, area.width, 1, format, type,
lastRowPixels); lastRowPixels);
} }
...@@ -466,24 +477,28 @@ gl::Error TextureGL::setCompressedImage(const gl::Context *context, ...@@ -466,24 +477,28 @@ gl::Error TextureGL::setCompressedImage(const gl::Context *context,
size_t imageSize, size_t imageSize,
const uint8_t *pixels) const uint8_t *pixels)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const WorkaroundsGL &workarounds = GetWorkaroundsGL(context);
gl::TextureTarget target = index.getTarget(); gl::TextureTarget target = index.getTarget();
size_t level = static_cast<size_t>(index.getLevelIndex()); size_t level = static_cast<size_t>(index.getLevelIndex());
ASSERT(TextureTargetToType(target) == getType()); ASSERT(TextureTargetToType(target) == getType());
nativegl::CompressedTexImageFormat compressedTexImageFormat = nativegl::CompressedTexImageFormat compressedTexImageFormat =
nativegl::GetCompressedTexImageFormat(mFunctions, mWorkarounds, internalFormat); nativegl::GetCompressedTexImageFormat(functions, workarounds, internalFormat);
mStateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
if (nativegl::UseTexImage2D(getType())) if (nativegl::UseTexImage2D(getType()))
{ {
ASSERT(size.depth == 1); ASSERT(size.depth == 1);
mFunctions->compressedTexImage2D(ToGLenum(target), static_cast<GLint>(level), functions->compressedTexImage2D(ToGLenum(target), static_cast<GLint>(level),
compressedTexImageFormat.internalFormat, size.width, compressedTexImageFormat.internalFormat, size.width,
size.height, 0, static_cast<GLsizei>(imageSize), pixels); size.height, 0, static_cast<GLsizei>(imageSize), pixels);
} }
else if (nativegl::UseTexImage3D(getType())) else if (nativegl::UseTexImage3D(getType()))
{ {
mFunctions->compressedTexImage3D( functions->compressedTexImage3D(
ToGLenum(target), static_cast<GLint>(level), compressedTexImageFormat.internalFormat, ToGLenum(target), static_cast<GLint>(level), compressedTexImageFormat.internalFormat,
size.width, size.height, size.depth, 0, static_cast<GLsizei>(imageSize), pixels); size.width, size.height, size.depth, 0, static_cast<GLsizei>(imageSize), pixels);
} }
...@@ -507,24 +522,28 @@ gl::Error TextureGL::setCompressedSubImage(const gl::Context *context, ...@@ -507,24 +522,28 @@ gl::Error TextureGL::setCompressedSubImage(const gl::Context *context,
size_t imageSize, size_t imageSize,
const uint8_t *pixels) const uint8_t *pixels)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const WorkaroundsGL &workarounds = GetWorkaroundsGL(context);
gl::TextureTarget target = index.getTarget(); gl::TextureTarget target = index.getTarget();
size_t level = static_cast<size_t>(index.getLevelIndex()); size_t level = static_cast<size_t>(index.getLevelIndex());
ASSERT(TextureTargetToType(target) == getType()); ASSERT(TextureTargetToType(target) == getType());
nativegl::CompressedTexSubImageFormat compressedTexSubImageFormat = nativegl::CompressedTexSubImageFormat compressedTexSubImageFormat =
nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, format); nativegl::GetCompressedSubTexImageFormat(functions, workarounds, format);
mStateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
if (nativegl::UseTexImage2D(getType())) if (nativegl::UseTexImage2D(getType()))
{ {
ASSERT(area.z == 0 && area.depth == 1); ASSERT(area.z == 0 && area.depth == 1);
mFunctions->compressedTexSubImage2D( functions->compressedTexSubImage2D(
ToGLenum(target), static_cast<GLint>(level), area.x, area.y, area.width, area.height, ToGLenum(target), static_cast<GLint>(level), area.x, area.y, area.width, area.height,
compressedTexSubImageFormat.format, static_cast<GLsizei>(imageSize), pixels); compressedTexSubImageFormat.format, static_cast<GLsizei>(imageSize), pixels);
} }
else if (nativegl::UseTexImage3D(getType())) else if (nativegl::UseTexImage3D(getType()))
{ {
mFunctions->compressedTexSubImage3D(ToGLenum(target), static_cast<GLint>(level), area.x, functions->compressedTexSubImage3D(ToGLenum(target), static_cast<GLint>(level), area.x,
area.y, area.z, area.width, area.height, area.depth, area.y, area.z, area.width, area.height, area.depth,
compressedTexSubImageFormat.format, compressedTexSubImageFormat.format,
static_cast<GLsizei>(imageSize), pixels); static_cast<GLsizei>(imageSize), pixels);
...@@ -546,14 +565,18 @@ gl::Error TextureGL::copyImage(const gl::Context *context, ...@@ -546,14 +565,18 @@ gl::Error TextureGL::copyImage(const gl::Context *context,
GLenum internalFormat, GLenum internalFormat,
gl::Framebuffer *source) gl::Framebuffer *source)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const WorkaroundsGL &workarounds = GetWorkaroundsGL(context);
gl::TextureTarget target = index.getTarget(); gl::TextureTarget target = index.getTarget();
size_t level = static_cast<size_t>(index.getLevelIndex()); size_t level = static_cast<size_t>(index.getLevelIndex());
GLenum type = GL_NONE; GLenum type = GL_NONE;
ANGLE_TRY(source->getImplementationColorReadType(context, &type)); ANGLE_TRY(source->getImplementationColorReadType(context, &type));
nativegl::CopyTexImageImageFormat copyTexImageFormat = nativegl::CopyTexImageImageFormat copyTexImageFormat =
nativegl::GetCopyTexImageImageFormat(mFunctions, mWorkarounds, internalFormat, type); nativegl::GetCopyTexImageImageFormat(functions, workarounds, internalFormat, type);
mStateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source); const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
gl::Extents fbSize = sourceFramebufferGL->getState().getReadAttachment()->getSize(); gl::Extents fbSize = sourceFramebufferGL->getState().getReadAttachment()->getSize();
...@@ -582,10 +605,10 @@ gl::Error TextureGL::copyImage(const gl::Context *context, ...@@ -582,10 +605,10 @@ gl::Error TextureGL::copyImage(const gl::Context *context,
gl::PixelUnpackState unpack; gl::PixelUnpackState unpack;
unpack.alignment = 1; unpack.alignment = 1;
mStateManager->setPixelUnpackState(unpack); stateManager->setPixelUnpackState(unpack);
mStateManager->setPixelUnpackBuffer(nullptr); stateManager->setPixelUnpackBuffer(nullptr);
mFunctions->texImage2D( functions->texImage2D(
ToGLenum(target), static_cast<GLint>(level), copyTexImageFormat.internalFormat, ToGLenum(target), static_cast<GLint>(level), copyTexImageFormat.internalFormat,
origSourceArea.width, origSourceArea.height, 0, origSourceArea.width, origSourceArea.height, 0,
gl::GetUnsizedFormat(copyTexImageFormat.internalFormat), type, zero->data()); gl::GetUnsizedFormat(copyTexImageFormat.internalFormat), type, zero->data());
...@@ -601,32 +624,34 @@ gl::Error TextureGL::copyImage(const gl::Context *context, ...@@ -601,32 +624,34 @@ gl::Error TextureGL::copyImage(const gl::Context *context,
if (levelInfo.lumaWorkaround.enabled) if (levelInfo.lumaWorkaround.enabled)
{ {
BlitGL *blitter = GetBlitGL(context);
if (requiresInitialization) if (requiresInitialization)
{ {
ANGLE_TRY(mBlitter->copySubImageToLUMAWorkaroundTexture( ANGLE_TRY(blitter->copySubImageToLUMAWorkaroundTexture(
context, mTextureID, getType(), target, levelInfo.sourceFormat, level, context, mTextureID, getType(), target, levelInfo.sourceFormat, level,
destOffset, sourceArea, source)); destOffset, sourceArea, source));
} }
else else
{ {
ANGLE_TRY(mBlitter->copyImageToLUMAWorkaroundTexture( ANGLE_TRY(blitter->copyImageToLUMAWorkaroundTexture(
context, mTextureID, getType(), target, levelInfo.sourceFormat, level, context, mTextureID, getType(), target, levelInfo.sourceFormat, level,
sourceArea, copyTexImageFormat.internalFormat, source)); sourceArea, copyTexImageFormat.internalFormat, source));
} }
} }
else if (nativegl::UseTexImage2D(getType())) else if (nativegl::UseTexImage2D(getType()))
{ {
mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, stateManager->bindFramebuffer(GL_READ_FRAMEBUFFER,
sourceFramebufferGL->getFramebufferID()); sourceFramebufferGL->getFramebufferID());
if (requiresInitialization) if (requiresInitialization)
{ {
mFunctions->copyTexSubImage2D(ToGLenum(target), static_cast<GLint>(level), functions->copyTexSubImage2D(ToGLenum(target), static_cast<GLint>(level),
destOffset.x, destOffset.y, sourceArea.x, destOffset.x, destOffset.y, sourceArea.x, sourceArea.y,
sourceArea.y, sourceArea.width, sourceArea.height); sourceArea.width, sourceArea.height);
} }
else else
{ {
mFunctions->copyTexImage2D(ToGLenum(target), static_cast<GLint>(level), functions->copyTexImage2D(ToGLenum(target), static_cast<GLint>(level),
copyTexImageFormat.internalFormat, sourceArea.x, copyTexImageFormat.internalFormat, sourceArea.x,
sourceArea.y, sourceArea.width, sourceArea.height, 0); sourceArea.y, sourceArea.width, sourceArea.height, 0);
} }
...@@ -648,6 +673,9 @@ gl::Error TextureGL::copySubImage(const gl::Context *context, ...@@ -648,6 +673,9 @@ gl::Error TextureGL::copySubImage(const gl::Context *context,
const gl::Rectangle &origSourceArea, const gl::Rectangle &origSourceArea,
gl::Framebuffer *source) gl::Framebuffer *source)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
gl::TextureTarget target = index.getTarget(); gl::TextureTarget target = index.getTarget();
size_t level = static_cast<size_t>(index.getLevelIndex()); size_t level = static_cast<size_t>(index.getLevelIndex());
const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source); const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
...@@ -664,13 +692,14 @@ gl::Error TextureGL::copySubImage(const gl::Context *context, ...@@ -664,13 +692,14 @@ gl::Error TextureGL::copySubImage(const gl::Context *context,
gl::Offset destOffset(origDestOffset.x + sourceArea.x - origSourceArea.x, gl::Offset destOffset(origDestOffset.x + sourceArea.x - origSourceArea.x,
origDestOffset.y + sourceArea.y - origSourceArea.y, origDestOffset.z); origDestOffset.y + sourceArea.y - origSourceArea.y, origDestOffset.z);
mStateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID()); stateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());
const LevelInfoGL &levelInfo = getLevelInfo(target, level); const LevelInfoGL &levelInfo = getLevelInfo(target, level);
if (levelInfo.lumaWorkaround.enabled) if (levelInfo.lumaWorkaround.enabled)
{ {
gl::Error error = mBlitter->copySubImageToLUMAWorkaroundTexture( BlitGL *blitter = GetBlitGL(context);
gl::Error error = blitter->copySubImageToLUMAWorkaroundTexture(
context, mTextureID, getType(), target, levelInfo.sourceFormat, level, destOffset, context, mTextureID, getType(), target, levelInfo.sourceFormat, level, destOffset,
sourceArea, source); sourceArea, source);
if (error.isError()) if (error.isError())
...@@ -683,13 +712,13 @@ gl::Error TextureGL::copySubImage(const gl::Context *context, ...@@ -683,13 +712,13 @@ gl::Error TextureGL::copySubImage(const gl::Context *context,
if (nativegl::UseTexImage2D(getType())) if (nativegl::UseTexImage2D(getType()))
{ {
ASSERT(destOffset.z == 0); ASSERT(destOffset.z == 0);
mFunctions->copyTexSubImage2D(ToGLenum(target), static_cast<GLint>(level), destOffset.x, functions->copyTexSubImage2D(ToGLenum(target), static_cast<GLint>(level), destOffset.x,
destOffset.y, sourceArea.x, sourceArea.y, destOffset.y, sourceArea.x, sourceArea.y, sourceArea.width,
sourceArea.width, sourceArea.height); sourceArea.height);
} }
else if (nativegl::UseTexImage3D(getType())) else if (nativegl::UseTexImage3D(getType()))
{ {
mFunctions->copyTexSubImage3D(ToGLenum(target), static_cast<GLint>(level), destOffset.x, functions->copyTexSubImage3D(ToGLenum(target), static_cast<GLint>(level), destOffset.x,
destOffset.y, destOffset.z, sourceArea.x, sourceArea.y, destOffset.y, destOffset.z, sourceArea.x, sourceArea.y,
sourceArea.width, sourceArea.height); sourceArea.width, sourceArea.height);
} }
...@@ -719,7 +748,7 @@ gl::Error TextureGL::copyTexture(const gl::Context *context, ...@@ -719,7 +748,7 @@ gl::Error TextureGL::copyTexture(const gl::Context *context,
sourceGL->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), sourceLevel); sourceGL->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), sourceLevel);
gl::Rectangle sourceArea(0, 0, sourceImageDesc.size.width, sourceImageDesc.size.height); gl::Rectangle sourceArea(0, 0, sourceImageDesc.size.width, sourceImageDesc.size.height);
reserveTexImageToBeFilled(target, level, internalFormat, sourceImageDesc.size, reserveTexImageToBeFilled(context, target, level, internalFormat, sourceImageDesc.size,
gl::GetUnsizedFormat(internalFormat), type); gl::GetUnsizedFormat(internalFormat), type);
const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(internalFormat, type); const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
...@@ -758,6 +787,9 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context, ...@@ -758,6 +787,9 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context,
bool unpackUnmultiplyAlpha, bool unpackUnmultiplyAlpha,
const gl::Texture *source) const gl::Texture *source)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
BlitGL *blitter = GetBlitGL(context);
TextureGL *sourceGL = GetImplAs<TextureGL>(source); TextureGL *sourceGL = GetImplAs<TextureGL>(source);
const gl::ImageDesc &sourceImageDesc = const gl::ImageDesc &sourceImageDesc =
sourceGL->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), sourceLevel); sourceGL->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), sourceLevel);
...@@ -781,7 +813,7 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context, ...@@ -781,7 +813,7 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context,
!destSRGB) !destSRGB)
{ {
bool copySucceded = false; bool copySucceded = false;
ANGLE_TRY_RESULT(mBlitter->copyTexSubImage(sourceGL, sourceLevel, this, target, level, ANGLE_TRY_RESULT(blitter->copyTexSubImage(sourceGL, sourceLevel, this, target, level,
sourceArea, destOffset), sourceArea, destOffset),
copySucceded); copySucceded);
if (copySucceded) if (copySucceded)
...@@ -792,11 +824,11 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context, ...@@ -792,11 +824,11 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context,
// Check if the destination is renderable and copy on the GPU // Check if the destination is renderable and copy on the GPU
const LevelInfoGL &destLevelInfo = getLevelInfo(target, level); const LevelInfoGL &destLevelInfo = getLevelInfo(target, level);
if (!destSRGB && nativegl::SupportsNativeRendering(mFunctions, getType(), if (!destSRGB &&
destLevelInfo.nativeInternalFormat)) nativegl::SupportsNativeRendering(functions, getType(), destLevelInfo.nativeInternalFormat))
{ {
bool copySucceded = false; bool copySucceded = false;
ANGLE_TRY_RESULT(mBlitter->copySubTexture( ANGLE_TRY_RESULT(blitter->copySubTexture(
context, sourceGL, sourceLevel, sourceComponentType, this, target, context, sourceGL, sourceLevel, sourceComponentType, this, target,
level, destComponentType, sourceImageDesc.size, sourceArea, destOffset, level, destComponentType, sourceImageDesc.size, sourceArea, destOffset,
needsLumaWorkaround, sourceLevelInfo.sourceFormat, unpackFlipY, needsLumaWorkaround, sourceLevelInfo.sourceFormat, unpackFlipY,
...@@ -809,7 +841,7 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context, ...@@ -809,7 +841,7 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context,
} }
// Fall back to CPU-readback // Fall back to CPU-readback
return mBlitter->copySubTextureCPUReadback(context, sourceGL, sourceLevel, sourceComponentType, return blitter->copySubTextureCPUReadback(context, sourceGL, sourceLevel, sourceComponentType,
this, target, level, destFormat.format, this, target, level, destFormat.format,
destFormat.type, sourceArea, destOffset, unpackFlipY, destFormat.type, sourceArea, destOffset, unpackFlipY,
unpackPremultiplyAlpha, unpackUnmultiplyAlpha); unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
...@@ -821,22 +853,26 @@ gl::Error TextureGL::setStorage(const gl::Context *context, ...@@ -821,22 +853,26 @@ gl::Error TextureGL::setStorage(const gl::Context *context,
GLenum internalFormat, GLenum internalFormat,
const gl::Extents &size) const gl::Extents &size)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const WorkaroundsGL &workarounds = GetWorkaroundsGL(context);
nativegl::TexStorageFormat texStorageFormat = nativegl::TexStorageFormat texStorageFormat =
nativegl::GetTexStorageFormat(mFunctions, mWorkarounds, internalFormat); nativegl::GetTexStorageFormat(functions, workarounds, internalFormat);
mStateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
if (nativegl::UseTexImage2D(getType())) if (nativegl::UseTexImage2D(getType()))
{ {
ASSERT(size.depth == 1); ASSERT(size.depth == 1);
if (mFunctions->texStorage2D) if (functions->texStorage2D)
{ {
mFunctions->texStorage2D(ToGLenum(type), static_cast<GLsizei>(levels), functions->texStorage2D(ToGLenum(type), static_cast<GLsizei>(levels),
texStorageFormat.internalFormat, size.width, size.height); texStorageFormat.internalFormat, size.width, size.height);
} }
else else
{ {
// Make sure no pixel unpack buffer is bound // Make sure no pixel unpack buffer is bound
mStateManager->bindBuffer(gl::BufferBinding::PixelUnpack, 0); stateManager->bindBuffer(gl::BufferBinding::PixelUnpack, 0);
const gl::InternalFormat &internalFormatInfo = const gl::InternalFormat &internalFormatInfo =
gl::GetSizedInternalFormatInfo(internalFormat); gl::GetSizedInternalFormatInfo(internalFormat);
...@@ -855,13 +891,13 @@ gl::Error TextureGL::setStorage(const gl::Context *context, ...@@ -855,13 +891,13 @@ gl::Error TextureGL::setStorage(const gl::Context *context,
if (internalFormatInfo.compressed) if (internalFormatInfo.compressed)
{ {
nativegl::CompressedTexSubImageFormat compressedTexImageFormat = nativegl::CompressedTexSubImageFormat compressedTexImageFormat =
nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, nativegl::GetCompressedSubTexImageFormat(functions, workarounds,
internalFormat); internalFormat);
GLuint dataSize = 0; GLuint dataSize = 0;
ANGLE_TRY_RESULT(internalFormatInfo.computeCompressedImageSize(levelSize), ANGLE_TRY_RESULT(internalFormatInfo.computeCompressedImageSize(levelSize),
dataSize); dataSize);
mFunctions->compressedTexImage2D(ToGLenum(type), static_cast<GLint>(level), functions->compressedTexImage2D(ToGLenum(type), static_cast<GLint>(level),
compressedTexImageFormat.format, compressedTexImageFormat.format,
levelSize.width, levelSize.height, 0, levelSize.width, levelSize.height, 0,
static_cast<GLsizei>(dataSize), nullptr); static_cast<GLsizei>(dataSize), nullptr);
...@@ -869,10 +905,10 @@ gl::Error TextureGL::setStorage(const gl::Context *context, ...@@ -869,10 +905,10 @@ gl::Error TextureGL::setStorage(const gl::Context *context,
else else
{ {
nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat( nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
mFunctions, mWorkarounds, internalFormat, internalFormatInfo.format, functions, workarounds, internalFormat, internalFormatInfo.format,
internalFormatInfo.type); internalFormatInfo.type);
mFunctions->texImage2D(ToGLenum(type), static_cast<GLint>(level), functions->texImage2D(ToGLenum(type), static_cast<GLint>(level),
texImageFormat.internalFormat, levelSize.width, texImageFormat.internalFormat, levelSize.width,
levelSize.height, 0, texImageFormat.format, levelSize.height, 0, texImageFormat.format,
texImageFormat.type, nullptr); texImageFormat.type, nullptr);
...@@ -885,13 +921,13 @@ gl::Error TextureGL::setStorage(const gl::Context *context, ...@@ -885,13 +921,13 @@ gl::Error TextureGL::setStorage(const gl::Context *context,
if (internalFormatInfo.compressed) if (internalFormatInfo.compressed)
{ {
nativegl::CompressedTexSubImageFormat compressedTexImageFormat = nativegl::CompressedTexSubImageFormat compressedTexImageFormat =
nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, nativegl::GetCompressedSubTexImageFormat(functions, workarounds,
internalFormat); internalFormat);
GLuint dataSize = 0; GLuint dataSize = 0;
ANGLE_TRY_RESULT(internalFormatInfo.computeCompressedImageSize(levelSize), ANGLE_TRY_RESULT(internalFormatInfo.computeCompressedImageSize(levelSize),
dataSize); dataSize);
mFunctions->compressedTexImage2D( functions->compressedTexImage2D(
ToGLenum(face), static_cast<GLint>(level), ToGLenum(face), static_cast<GLint>(level),
compressedTexImageFormat.format, levelSize.width, levelSize.height, compressedTexImageFormat.format, levelSize.width, levelSize.height,
0, static_cast<GLsizei>(dataSize), nullptr); 0, static_cast<GLsizei>(dataSize), nullptr);
...@@ -899,10 +935,10 @@ gl::Error TextureGL::setStorage(const gl::Context *context, ...@@ -899,10 +935,10 @@ gl::Error TextureGL::setStorage(const gl::Context *context,
else else
{ {
nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat( nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
mFunctions, mWorkarounds, internalFormat, internalFormatInfo.format, functions, workarounds, internalFormat, internalFormatInfo.format,
internalFormatInfo.type); internalFormatInfo.type);
mFunctions->texImage2D(ToGLenum(face), static_cast<GLint>(level), functions->texImage2D(ToGLenum(face), static_cast<GLint>(level),
texImageFormat.internalFormat, levelSize.width, texImageFormat.internalFormat, levelSize.width,
levelSize.height, 0, texImageFormat.format, levelSize.height, 0, texImageFormat.format,
texImageFormat.type, nullptr); texImageFormat.type, nullptr);
...@@ -918,16 +954,16 @@ gl::Error TextureGL::setStorage(const gl::Context *context, ...@@ -918,16 +954,16 @@ gl::Error TextureGL::setStorage(const gl::Context *context,
} }
else if (nativegl::UseTexImage3D(getType())) else if (nativegl::UseTexImage3D(getType()))
{ {
if (mFunctions->texStorage3D) if (functions->texStorage3D)
{ {
mFunctions->texStorage3D(ToGLenum(type), static_cast<GLsizei>(levels), functions->texStorage3D(ToGLenum(type), static_cast<GLsizei>(levels),
texStorageFormat.internalFormat, size.width, size.height, texStorageFormat.internalFormat, size.width, size.height,
size.depth); size.depth);
} }
else else
{ {
// Make sure no pixel unpack buffer is bound // Make sure no pixel unpack buffer is bound
mStateManager->bindBuffer(gl::BufferBinding::PixelUnpack, 0); stateManager->bindBuffer(gl::BufferBinding::PixelUnpack, 0);
const gl::InternalFormat &internalFormatInfo = const gl::InternalFormat &internalFormatInfo =
gl::GetSizedInternalFormatInfo(internalFormat); gl::GetSizedInternalFormatInfo(internalFormat);
...@@ -944,14 +980,14 @@ gl::Error TextureGL::setStorage(const gl::Context *context, ...@@ -944,14 +980,14 @@ gl::Error TextureGL::setStorage(const gl::Context *context,
if (internalFormatInfo.compressed) if (internalFormatInfo.compressed)
{ {
nativegl::CompressedTexSubImageFormat compressedTexImageFormat = nativegl::CompressedTexSubImageFormat compressedTexImageFormat =
nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, nativegl::GetCompressedSubTexImageFormat(functions, workarounds,
internalFormat); internalFormat);
GLuint dataSize = 0; GLuint dataSize = 0;
ANGLE_TRY_RESULT( ANGLE_TRY_RESULT(
internalFormatInfo.computeCompressedImageSize(levelSize), internalFormatInfo.computeCompressedImageSize(levelSize),
dataSize); dataSize);
mFunctions->compressedTexImage3D( functions->compressedTexImage3D(
ToGLenum(type), i, compressedTexImageFormat.format, levelSize.width, ToGLenum(type), i, compressedTexImageFormat.format, levelSize.width,
levelSize.height, levelSize.depth, 0, static_cast<GLsizei>(dataSize), levelSize.height, levelSize.depth, 0, static_cast<GLsizei>(dataSize),
nullptr); nullptr);
...@@ -959,10 +995,10 @@ gl::Error TextureGL::setStorage(const gl::Context *context, ...@@ -959,10 +995,10 @@ gl::Error TextureGL::setStorage(const gl::Context *context,
else else
{ {
nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat( nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
mFunctions, mWorkarounds, internalFormat, internalFormatInfo.format, functions, workarounds, internalFormat, internalFormatInfo.format,
internalFormatInfo.type); internalFormatInfo.type);
mFunctions->texImage3D(ToGLenum(type), i, texImageFormat.internalFormat, functions->texImage3D(ToGLenum(type), i, texImageFormat.internalFormat,
levelSize.width, levelSize.height, levelSize.depth, 0, levelSize.width, levelSize.height, levelSize.depth, 0,
texImageFormat.format, texImageFormat.type, nullptr); texImageFormat.format, texImageFormat.type, nullptr);
} }
...@@ -986,14 +1022,18 @@ gl::Error TextureGL::setStorageMultisample(const gl::Context *context, ...@@ -986,14 +1022,18 @@ gl::Error TextureGL::setStorageMultisample(const gl::Context *context,
const gl::Extents &size, const gl::Extents &size,
bool fixedSampleLocations) bool fixedSampleLocations)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const WorkaroundsGL &workarounds = GetWorkaroundsGL(context);
nativegl::TexStorageFormat texStorageFormat = nativegl::TexStorageFormat texStorageFormat =
nativegl::GetTexStorageFormat(mFunctions, mWorkarounds, internalFormat); nativegl::GetTexStorageFormat(functions, workarounds, internalFormat);
mStateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
ASSERT(size.depth == 1); ASSERT(size.depth == 1);
mFunctions->texStorage2DMultisample(ToGLenum(type), samples, texStorageFormat.internalFormat, functions->texStorage2DMultisample(ToGLenum(type), samples, texStorageFormat.internalFormat,
size.width, size.height, size.width, size.height,
gl::ConvertToGLBoolean(fixedSampleLocations)); gl::ConvertToGLBoolean(fixedSampleLocations));
...@@ -1013,8 +1053,11 @@ gl::Error TextureGL::setImageExternal(const gl::Context *context, ...@@ -1013,8 +1053,11 @@ gl::Error TextureGL::setImageExternal(const gl::Context *context,
gl::Error TextureGL::generateMipmap(const gl::Context *context) gl::Error TextureGL::generateMipmap(const gl::Context *context)
{ {
mStateManager->bindTexture(getType(), mTextureID); const FunctionsGL *functions = GetFunctionsGL(context);
mFunctions->generateMipmap(ToGLenum(getType())); StateManagerGL *stateManager = GetStateManagerGL(context);
stateManager->bindTexture(getType(), mTextureID);
functions->generateMipmap(ToGLenum(getType()));
const GLuint effectiveBaseLevel = mState.getEffectiveBaseLevel(); const GLuint effectiveBaseLevel = mState.getEffectiveBaseLevel();
const GLuint maxLevel = mState.getMipmapMaxLevel(); const GLuint maxLevel = mState.getMipmapMaxLevel();
...@@ -1028,8 +1071,10 @@ gl::Error TextureGL::bindTexImage(const gl::Context *context, egl::Surface *surf ...@@ -1028,8 +1071,10 @@ gl::Error TextureGL::bindTexImage(const gl::Context *context, egl::Surface *surf
{ {
ASSERT(getType() == gl::TextureType::_2D || getType() == gl::TextureType::Rectangle); ASSERT(getType() == gl::TextureType::_2D || getType() == gl::TextureType::Rectangle);
StateManagerGL *stateManager = GetStateManagerGL(context);
// Make sure this texture is bound // Make sure this texture is bound
mStateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
setLevelInfo(getType(), 0, 1, LevelInfoGL()); setLevelInfo(getType(), 0, 1, LevelInfoGL());
return gl::NoError(); return gl::NoError();
...@@ -1040,10 +1085,13 @@ gl::Error TextureGL::releaseTexImage(const gl::Context *context) ...@@ -1040,10 +1085,13 @@ gl::Error TextureGL::releaseTexImage(const gl::Context *context)
// Not all Surface implementations reset the size of mip 0 when releasing, do it manually // Not all Surface implementations reset the size of mip 0 when releasing, do it manually
ASSERT(getType() == gl::TextureType::_2D || getType() == gl::TextureType::Rectangle); ASSERT(getType() == gl::TextureType::_2D || getType() == gl::TextureType::Rectangle);
mStateManager->bindTexture(getType(), mTextureID); const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
stateManager->bindTexture(getType(), mTextureID);
if (nativegl::UseTexImage2D(getType())) if (nativegl::UseTexImage2D(getType()))
{ {
mFunctions->texImage2D(ToGLenum(getType()), 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, functions->texImage2D(ToGLenum(getType()), 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE,
nullptr); nullptr);
} }
else else
...@@ -1068,7 +1116,10 @@ gl::Error TextureGL::syncState(const gl::Context *context, const gl::Texture::Di ...@@ -1068,7 +1116,10 @@ gl::Error TextureGL::syncState(const gl::Context *context, const gl::Texture::Di
return gl::NoError(); return gl::NoError();
} }
mStateManager->bindTexture(getType(), mTextureID); const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
stateManager->bindTexture(getType(), mTextureID);
if (dirtyBits[gl::Texture::DIRTY_BIT_BASE_LEVEL] || dirtyBits[gl::Texture::DIRTY_BIT_MAX_LEVEL]) if (dirtyBits[gl::Texture::DIRTY_BIT_BASE_LEVEL] || dirtyBits[gl::Texture::DIRTY_BIT_MAX_LEVEL])
{ {
...@@ -1083,95 +1134,95 @@ gl::Error TextureGL::syncState(const gl::Context *context, const gl::Texture::Di ...@@ -1083,95 +1134,95 @@ gl::Error TextureGL::syncState(const gl::Context *context, const gl::Texture::Di
{ {
case gl::Texture::DIRTY_BIT_MIN_FILTER: case gl::Texture::DIRTY_BIT_MIN_FILTER:
mAppliedSampler.minFilter = mState.getSamplerState().minFilter; mAppliedSampler.minFilter = mState.getSamplerState().minFilter;
mFunctions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MIN_FILTER, functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MIN_FILTER,
mAppliedSampler.minFilter); mAppliedSampler.minFilter);
break; break;
case gl::Texture::DIRTY_BIT_MAG_FILTER: case gl::Texture::DIRTY_BIT_MAG_FILTER:
mAppliedSampler.magFilter = mState.getSamplerState().magFilter; mAppliedSampler.magFilter = mState.getSamplerState().magFilter;
mFunctions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MAG_FILTER, functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MAG_FILTER,
mAppliedSampler.magFilter); mAppliedSampler.magFilter);
break; break;
case gl::Texture::DIRTY_BIT_WRAP_S: case gl::Texture::DIRTY_BIT_WRAP_S:
mAppliedSampler.wrapS = mState.getSamplerState().wrapS; mAppliedSampler.wrapS = mState.getSamplerState().wrapS;
mFunctions->texParameteri(ToGLenum(getType()), GL_TEXTURE_WRAP_S, functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_WRAP_S,
mAppliedSampler.wrapS); mAppliedSampler.wrapS);
break; break;
case gl::Texture::DIRTY_BIT_WRAP_T: case gl::Texture::DIRTY_BIT_WRAP_T:
mAppliedSampler.wrapT = mState.getSamplerState().wrapT; mAppliedSampler.wrapT = mState.getSamplerState().wrapT;
mFunctions->texParameteri(ToGLenum(getType()), GL_TEXTURE_WRAP_T, functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_WRAP_T,
mAppliedSampler.wrapT); mAppliedSampler.wrapT);
break; break;
case gl::Texture::DIRTY_BIT_WRAP_R: case gl::Texture::DIRTY_BIT_WRAP_R:
mAppliedSampler.wrapR = mState.getSamplerState().wrapR; mAppliedSampler.wrapR = mState.getSamplerState().wrapR;
mFunctions->texParameteri(ToGLenum(getType()), GL_TEXTURE_WRAP_R, functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_WRAP_R,
mAppliedSampler.wrapR); mAppliedSampler.wrapR);
break; break;
case gl::Texture::DIRTY_BIT_MAX_ANISOTROPY: case gl::Texture::DIRTY_BIT_MAX_ANISOTROPY:
mAppliedSampler.maxAnisotropy = mState.getSamplerState().maxAnisotropy; mAppliedSampler.maxAnisotropy = mState.getSamplerState().maxAnisotropy;
mFunctions->texParameterf(ToGLenum(getType()), GL_TEXTURE_MAX_ANISOTROPY_EXT, functions->texParameterf(ToGLenum(getType()), GL_TEXTURE_MAX_ANISOTROPY_EXT,
mAppliedSampler.maxAnisotropy); mAppliedSampler.maxAnisotropy);
break; break;
case gl::Texture::DIRTY_BIT_MIN_LOD: case gl::Texture::DIRTY_BIT_MIN_LOD:
mAppliedSampler.minLod = mState.getSamplerState().minLod; mAppliedSampler.minLod = mState.getSamplerState().minLod;
mFunctions->texParameterf(ToGLenum(getType()), GL_TEXTURE_MIN_LOD, functions->texParameterf(ToGLenum(getType()), GL_TEXTURE_MIN_LOD,
mAppliedSampler.minLod); mAppliedSampler.minLod);
break; break;
case gl::Texture::DIRTY_BIT_MAX_LOD: case gl::Texture::DIRTY_BIT_MAX_LOD:
mAppliedSampler.maxLod = mState.getSamplerState().maxLod; mAppliedSampler.maxLod = mState.getSamplerState().maxLod;
mFunctions->texParameterf(ToGLenum(getType()), GL_TEXTURE_MAX_LOD, functions->texParameterf(ToGLenum(getType()), GL_TEXTURE_MAX_LOD,
mAppliedSampler.maxLod); mAppliedSampler.maxLod);
break; break;
case gl::Texture::DIRTY_BIT_COMPARE_MODE: case gl::Texture::DIRTY_BIT_COMPARE_MODE:
mAppliedSampler.compareMode = mState.getSamplerState().compareMode; mAppliedSampler.compareMode = mState.getSamplerState().compareMode;
mFunctions->texParameteri(ToGLenum(getType()), GL_TEXTURE_COMPARE_MODE, functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_COMPARE_MODE,
mAppliedSampler.compareMode); mAppliedSampler.compareMode);
break; break;
case gl::Texture::DIRTY_BIT_COMPARE_FUNC: case gl::Texture::DIRTY_BIT_COMPARE_FUNC:
mAppliedSampler.compareFunc = mState.getSamplerState().compareFunc; mAppliedSampler.compareFunc = mState.getSamplerState().compareFunc;
mFunctions->texParameteri(ToGLenum(getType()), GL_TEXTURE_COMPARE_FUNC, functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_COMPARE_FUNC,
mAppliedSampler.compareFunc); mAppliedSampler.compareFunc);
break; break;
case gl::Texture::DIRTY_BIT_SRGB_DECODE: case gl::Texture::DIRTY_BIT_SRGB_DECODE:
mAppliedSampler.sRGBDecode = mState.getSamplerState().sRGBDecode; mAppliedSampler.sRGBDecode = mState.getSamplerState().sRGBDecode;
mFunctions->texParameteri(ToGLenum(getType()), GL_TEXTURE_SRGB_DECODE_EXT, functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_SRGB_DECODE_EXT,
mAppliedSampler.sRGBDecode); mAppliedSampler.sRGBDecode);
break; break;
// Texture state // Texture state
case gl::Texture::DIRTY_BIT_SWIZZLE_RED: case gl::Texture::DIRTY_BIT_SWIZZLE_RED:
syncTextureStateSwizzle(mFunctions, GL_TEXTURE_SWIZZLE_R, syncTextureStateSwizzle(functions, GL_TEXTURE_SWIZZLE_R,
mState.getSwizzleState().swizzleRed, mState.getSwizzleState().swizzleRed,
&mAppliedSwizzle.swizzleRed); &mAppliedSwizzle.swizzleRed);
break; break;
case gl::Texture::DIRTY_BIT_SWIZZLE_GREEN: case gl::Texture::DIRTY_BIT_SWIZZLE_GREEN:
syncTextureStateSwizzle(mFunctions, GL_TEXTURE_SWIZZLE_G, syncTextureStateSwizzle(functions, GL_TEXTURE_SWIZZLE_G,
mState.getSwizzleState().swizzleGreen, mState.getSwizzleState().swizzleGreen,
&mAppliedSwizzle.swizzleGreen); &mAppliedSwizzle.swizzleGreen);
break; break;
case gl::Texture::DIRTY_BIT_SWIZZLE_BLUE: case gl::Texture::DIRTY_BIT_SWIZZLE_BLUE:
syncTextureStateSwizzle(mFunctions, GL_TEXTURE_SWIZZLE_B, syncTextureStateSwizzle(functions, GL_TEXTURE_SWIZZLE_B,
mState.getSwizzleState().swizzleBlue, mState.getSwizzleState().swizzleBlue,
&mAppliedSwizzle.swizzleBlue); &mAppliedSwizzle.swizzleBlue);
break; break;
case gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA: case gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA:
syncTextureStateSwizzle(mFunctions, GL_TEXTURE_SWIZZLE_A, syncTextureStateSwizzle(functions, GL_TEXTURE_SWIZZLE_A,
mState.getSwizzleState().swizzleAlpha, mState.getSwizzleState().swizzleAlpha,
&mAppliedSwizzle.swizzleAlpha); &mAppliedSwizzle.swizzleAlpha);
break; break;
case gl::Texture::DIRTY_BIT_BASE_LEVEL: case gl::Texture::DIRTY_BIT_BASE_LEVEL:
mAppliedBaseLevel = mState.getEffectiveBaseLevel(); mAppliedBaseLevel = mState.getEffectiveBaseLevel();
mFunctions->texParameteri(ToGLenum(getType()), GL_TEXTURE_BASE_LEVEL, functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_BASE_LEVEL,
mAppliedBaseLevel); mAppliedBaseLevel);
break; break;
case gl::Texture::DIRTY_BIT_MAX_LEVEL: case gl::Texture::DIRTY_BIT_MAX_LEVEL:
mAppliedMaxLevel = mState.getEffectiveMaxLevel(); mAppliedMaxLevel = mState.getEffectiveMaxLevel();
mFunctions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MAX_LEVEL, functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MAX_LEVEL,
mAppliedMaxLevel); mAppliedMaxLevel);
break; break;
case gl::Texture::DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE: case gl::Texture::DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE:
{ {
GLenum mDepthStencilTextureMode = mState.getDepthStencilTextureMode(); GLenum mDepthStencilTextureMode = mState.getDepthStencilTextureMode();
mFunctions->texParameteri(ToGLenum(getType()), GL_DEPTH_STENCIL_TEXTURE_MODE, functions->texParameteri(ToGLenum(getType()), GL_DEPTH_STENCIL_TEXTURE_MODE,
mDepthStencilTextureMode); mDepthStencilTextureMode);
break; break;
} }
...@@ -1198,53 +1249,65 @@ gl::Error TextureGL::setBaseLevel(const gl::Context *context, GLuint baseLevel) ...@@ -1198,53 +1249,65 @@ gl::Error TextureGL::setBaseLevel(const gl::Context *context, GLuint baseLevel)
{ {
if (baseLevel != mAppliedBaseLevel) if (baseLevel != mAppliedBaseLevel)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
mAppliedBaseLevel = baseLevel; mAppliedBaseLevel = baseLevel;
mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_BASE_LEVEL); mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_BASE_LEVEL);
mStateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
mFunctions->texParameteri(ToGLenum(getType()), GL_TEXTURE_BASE_LEVEL, baseLevel); functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_BASE_LEVEL, baseLevel);
} }
return gl::NoError(); return gl::NoError();
} }
void TextureGL::setMinFilter(GLenum filter) void TextureGL::setMinFilter(const gl::Context *context, GLenum filter)
{ {
if (filter != mAppliedSampler.minFilter) if (filter != mAppliedSampler.minFilter)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
mAppliedSampler.minFilter = filter; mAppliedSampler.minFilter = filter;
mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_MIN_FILTER); mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_MIN_FILTER);
mStateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
mFunctions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MIN_FILTER, filter); functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MIN_FILTER, filter);
} }
} }
void TextureGL::setMagFilter(GLenum filter) void TextureGL::setMagFilter(const gl::Context *context, GLenum filter)
{ {
if (filter != mAppliedSampler.magFilter) if (filter != mAppliedSampler.magFilter)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
mAppliedSampler.magFilter = filter; mAppliedSampler.magFilter = filter;
mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_MAG_FILTER); mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_MAG_FILTER);
mStateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
mFunctions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MAG_FILTER, filter); functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MAG_FILTER, filter);
} }
} }
void TextureGL::setSwizzle(GLint swizzle[4]) void TextureGL::setSwizzle(const gl::Context *context, GLint swizzle[4])
{ {
gl::SwizzleState resultingSwizzle = gl::SwizzleState resultingSwizzle =
gl::SwizzleState(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); gl::SwizzleState(swizzle[0], swizzle[1], swizzle[2], swizzle[3]);
if (resultingSwizzle != mAppliedSwizzle) if (resultingSwizzle != mAppliedSwizzle)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
mAppliedSwizzle = resultingSwizzle; mAppliedSwizzle = resultingSwizzle;
mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_RED); mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_RED);
mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_GREEN); mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_GREEN);
mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_BLUE); mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_BLUE);
mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA); mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA);
mStateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
mFunctions->texParameteriv(ToGLenum(getType()), GL_TEXTURE_SWIZZLE_RGBA, swizzle); functions->texParameteriv(ToGLenum(getType()), GL_TEXTURE_SWIZZLE_RGBA, swizzle);
} }
} }
...@@ -1435,15 +1498,21 @@ gl::TextureType TextureGL::getType() const ...@@ -1435,15 +1498,21 @@ gl::TextureType TextureGL::getType() const
gl::Error TextureGL::initializeContents(const gl::Context *context, gl::Error TextureGL::initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex) const gl::ImageIndex &imageIndex)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const WorkaroundsGL &workarounds = GetWorkaroundsGL(context);
GLenum nativeInternalFormat = GLenum nativeInternalFormat =
getLevelInfo(imageIndex.getTarget(), imageIndex.getLevelIndex()).nativeInternalFormat; getLevelInfo(imageIndex.getTarget(), imageIndex.getLevelIndex()).nativeInternalFormat;
if (nativegl::SupportsNativeRendering(mFunctions, mState.getType(), nativeInternalFormat)) if (nativegl::SupportsNativeRendering(functions, mState.getType(), nativeInternalFormat))
{ {
BlitGL *blitter = GetBlitGL(context);
int levelDepth = mState.getImageDesc(imageIndex).size.depth; int levelDepth = mState.getImageDesc(imageIndex).size.depth;
bool clearSucceeded = false; bool clearSucceeded = false;
ANGLE_TRY_RESULT( ANGLE_TRY_RESULT(
mBlitter->clearRenderableTexture(this, nativeInternalFormat, levelDepth, imageIndex), blitter->clearRenderableTexture(this, nativeInternalFormat, levelDepth, imageIndex),
clearSucceeded); clearSucceeded);
if (clearSucceeded) if (clearSucceeded)
{ {
...@@ -1458,12 +1527,12 @@ gl::Error TextureGL::initializeContents(const gl::Context *context, ...@@ -1458,12 +1527,12 @@ gl::Error TextureGL::initializeContents(const gl::Context *context,
gl::PixelUnpackState unpackState; gl::PixelUnpackState unpackState;
unpackState.alignment = 1; unpackState.alignment = 1;
mStateManager->setPixelUnpackState(unpackState); stateManager->setPixelUnpackState(unpackState);
if (internalFormatInfo.compressed) if (internalFormatInfo.compressed)
{ {
nativegl::CompressedTexSubImageFormat nativeSubImageFormat = nativegl::CompressedTexSubImageFormat nativeSubImageFormat =
nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, nativegl::GetCompressedSubTexImageFormat(functions, workarounds,
internalFormatInfo.internalFormat); internalFormatInfo.internalFormat);
GLuint imageSize = 0; GLuint imageSize = 0;
...@@ -1476,14 +1545,14 @@ gl::Error TextureGL::initializeContents(const gl::Context *context, ...@@ -1476,14 +1545,14 @@ gl::Error TextureGL::initializeContents(const gl::Context *context,
// not result in zero color data. // not result in zero color data.
if (nativegl::UseTexImage2D(getType())) if (nativegl::UseTexImage2D(getType()))
{ {
mFunctions->compressedTexSubImage2D( functions->compressedTexSubImage2D(
ToGLenum(imageIndex.getTarget()), imageIndex.getLevelIndex(), 0, 0, desc.size.width, ToGLenum(imageIndex.getTarget()), imageIndex.getLevelIndex(), 0, 0, desc.size.width,
desc.size.height, nativeSubImageFormat.format, imageSize, zero->data()); desc.size.height, nativeSubImageFormat.format, imageSize, zero->data());
} }
else else
{ {
ASSERT(nativegl::UseTexImage3D(getType())); ASSERT(nativegl::UseTexImage3D(getType()));
mFunctions->compressedTexSubImage3D( functions->compressedTexSubImage3D(
ToGLenum(imageIndex.getTarget()), imageIndex.getLevelIndex(), 0, 0, 0, ToGLenum(imageIndex.getTarget()), imageIndex.getLevelIndex(), 0, 0, 0,
desc.size.width, desc.size.height, desc.size.depth, nativeSubImageFormat.format, desc.size.width, desc.size.height, desc.size.depth, nativeSubImageFormat.format,
imageSize, zero->data()); imageSize, zero->data());
...@@ -1492,7 +1561,7 @@ gl::Error TextureGL::initializeContents(const gl::Context *context, ...@@ -1492,7 +1561,7 @@ gl::Error TextureGL::initializeContents(const gl::Context *context,
else else
{ {
nativegl::TexSubImageFormat nativeSubImageFormat = nativegl::GetTexSubImageFormat( nativegl::TexSubImageFormat nativeSubImageFormat = nativegl::GetTexSubImageFormat(
mFunctions, mWorkarounds, internalFormatInfo.format, internalFormatInfo.type); functions, workarounds, internalFormatInfo.format, internalFormatInfo.type);
GLuint imageSize = 0; GLuint imageSize = 0;
ANGLE_TRY_RESULT(internalFormatInfo.computePackUnpackEndByte( ANGLE_TRY_RESULT(internalFormatInfo.computePackUnpackEndByte(
...@@ -1505,7 +1574,7 @@ gl::Error TextureGL::initializeContents(const gl::Context *context, ...@@ -1505,7 +1574,7 @@ gl::Error TextureGL::initializeContents(const gl::Context *context,
if (nativegl::UseTexImage2D(getType())) if (nativegl::UseTexImage2D(getType()))
{ {
mFunctions->texSubImage2D(ToGLenum(imageIndex.getTarget()), imageIndex.getLevelIndex(), functions->texSubImage2D(ToGLenum(imageIndex.getTarget()), imageIndex.getLevelIndex(),
0, 0, desc.size.width, desc.size.height, 0, 0, desc.size.width, desc.size.height,
nativeSubImageFormat.format, nativeSubImageFormat.type, nativeSubImageFormat.format, nativeSubImageFormat.type,
zero->data()); zero->data());
...@@ -1513,7 +1582,7 @@ gl::Error TextureGL::initializeContents(const gl::Context *context, ...@@ -1513,7 +1582,7 @@ gl::Error TextureGL::initializeContents(const gl::Context *context,
else else
{ {
ASSERT(nativegl::UseTexImage3D(getType())); ASSERT(nativegl::UseTexImage3D(getType()));
mFunctions->texSubImage3D(ToGLenum(imageIndex.getTarget()), imageIndex.getLevelIndex(), functions->texSubImage3D(ToGLenum(imageIndex.getTarget()), imageIndex.getLevelIndex(),
0, 0, 0, desc.size.width, desc.size.height, desc.size.depth, 0, 0, 0, desc.size.width, desc.size.height, desc.size.depth,
nativeSubImageFormat.format, nativeSubImageFormat.type, nativeSubImageFormat.format, nativeSubImageFormat.type,
zero->data()); zero->data());
......
...@@ -56,13 +56,11 @@ struct LevelInfoGL ...@@ -56,13 +56,11 @@ struct LevelInfoGL
class TextureGL : public TextureImpl class TextureGL : public TextureImpl
{ {
public: public:
TextureGL(const gl::TextureState &state, TextureGL(const gl::TextureState &state, GLuint id);
const FunctionsGL *functions,
const WorkaroundsGL &workarounds,
StateManagerGL *stateManager,
BlitGL *blitter);
~TextureGL() override; ~TextureGL() override;
gl::Error onDestroy(const gl::Context *context) override;
gl::Error setImage(const gl::Context *context, gl::Error setImage(const gl::Context *context,
const gl::ImageIndex &index, const gl::ImageIndex &index,
GLenum internalFormat, GLenum internalFormat,
...@@ -174,13 +172,14 @@ class TextureGL : public TextureImpl ...@@ -174,13 +172,14 @@ class TextureGL : public TextureImpl
gl::Error initializeContents(const gl::Context *context, gl::Error initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex) override; const gl::ImageIndex &imageIndex) override;
void setMinFilter(GLenum filter); void setMinFilter(const gl::Context *context, GLenum filter);
void setMagFilter(GLenum filter); void setMagFilter(const gl::Context *context, GLenum filter);
void setSwizzle(GLint swizzle[4]); void setSwizzle(const gl::Context *context, GLint swizzle[4]);
private: private:
void setImageHelper(gl::TextureTarget target, void setImageHelper(const gl::Context *context,
gl::TextureTarget target,
size_t level, size_t level,
GLenum internalFormat, GLenum internalFormat,
const gl::Extents &size, const gl::Extents &size,
...@@ -188,7 +187,8 @@ class TextureGL : public TextureImpl ...@@ -188,7 +187,8 @@ class TextureGL : public TextureImpl
GLenum type, GLenum type,
const uint8_t *pixels); const uint8_t *pixels);
// This changes the current pixel unpack state that will have to be reapplied. // This changes the current pixel unpack state that will have to be reapplied.
void reserveTexImageToBeFilled(gl::TextureTarget target, void reserveTexImageToBeFilled(const gl::Context *context,
gl::TextureTarget target,
size_t level, size_t level,
GLenum internalFormat, GLenum internalFormat,
const gl::Extents &size, const gl::Extents &size,
...@@ -230,11 +230,6 @@ class TextureGL : public TextureImpl ...@@ -230,11 +230,6 @@ class TextureGL : public TextureImpl
const LevelInfoGL &getLevelInfo(gl::TextureTarget target, size_t level) const; const LevelInfoGL &getLevelInfo(gl::TextureTarget target, size_t level) const;
const LevelInfoGL &getBaseLevelInfo() const; const LevelInfoGL &getBaseLevelInfo() const;
const FunctionsGL *mFunctions;
const WorkaroundsGL &mWorkarounds;
StateManagerGL *mStateManager;
BlitGL *mBlitter;
std::vector<LevelInfoGL> mLevelInfo; std::vector<LevelInfoGL> mLevelInfo;
gl::Texture::DirtyBits mLocalDirtyBits; gl::Texture::DirtyBits mLocalDirtyBits;
......
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