gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) { ASSERT(CompatibleTextureTarget(mState.mTarget, target)); nativegl::CompressedTexSubImageFormat compressedTexSubImageFormat = nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, format); mStateManager->bindTexture(mState.mTarget, mTextureID); if (UseTexImage2D(mState.mTarget)) { ASSERT(area.z == 0 && area.depth == 1); mFunctions->compressedTexSubImage2D( target, static_cast<GLint>(level), area.x, area.y, area.width, area.height, compressedTexSubImageFormat.format, static_cast<GLsizei>(imageSize), pixels); } else if (UseTexImage3D(mState.mTarget)) { mFunctions->compressedTexSubImage3D(target, static_cast<GLint>(level), area.x, area.y, area.z, area.width, area.height, area.depth, compressedTexSubImageFormat.format, static_cast<GLsizei>(imageSize), pixels); } else { UNREACHABLE(); } ASSERT(!mLevelInfo[level].lumaWorkaround.enabled && !GetLevelInfo(format, compressedTexSubImageFormat.format).lumaWorkaround.enabled); return gl::Error(GL_NO_ERROR); }
gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) { ASSERT(CompatibleTextureTarget(mState.mTarget, target)); nativegl::CompressedTexImageFormat compressedTexImageFormat = nativegl::GetCompressedTexImageFormat(mFunctions, mWorkarounds, internalFormat); mStateManager->bindTexture(mState.mTarget, mTextureID); if (UseTexImage2D(mState.mTarget)) { ASSERT(size.depth == 1); mFunctions->compressedTexImage2D(target, static_cast<GLint>(level), compressedTexImageFormat.internalFormat, size.width, size.height, 0, static_cast<GLsizei>(imageSize), pixels); } else if (UseTexImage3D(mState.mTarget)) { mFunctions->compressedTexImage3D( target, static_cast<GLint>(level), compressedTexImageFormat.internalFormat, size.width, size.height, size.depth, 0, static_cast<GLsizei>(imageSize), pixels); } else { UNREACHABLE(); } mLevelInfo[level] = GetLevelInfo(internalFormat, compressedTexImageFormat.internalFormat); ASSERT(!mLevelInfo[level].lumaWorkaround.enabled); return gl::Error(GL_NO_ERROR); }
gl::Error TextureGL::copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) { const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source); mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID()); if (UseTexImage2D(mTextureType)) { ASSERT(destOffset.z == 0); mFunctions->copyTexSubImage2D(target, static_cast<GLint>(level), destOffset.x, destOffset.y, sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height); } else if (UseTexImage3D(mTextureType)) { mFunctions->copyTexSubImage3D(target, static_cast<GLint>(level), destOffset.x, destOffset.y, destOffset.z, sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height); } else { UNREACHABLE(); } return gl::Error(GL_NO_ERROR); }
gl::Error TextureGL::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const uint8_t *pixels) { ASSERT(CompatibleTextureTarget(mTextureType, target)); nativegl::TexSubImageFormat texSubImageFormat = nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type); mStateManager->bindTexture(mTextureType, mTextureID); if (UseTexImage2D(mTextureType)) { ASSERT(area.z == 0 && area.depth == 1); mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x, area.y, area.width, area.height, texSubImageFormat.format, texSubImageFormat.type, pixels); } else if (UseTexImage3D(mTextureType)) { mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, area.y, area.z, area.width, area.height, area.depth, texSubImageFormat.format, texSubImageFormat.type, pixels); } else { UNREACHABLE(); } return gl::Error(GL_NO_ERROR); }
gl::Error TextureGL::copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) { const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source); mStateManager->bindTexture(mState.mTarget, mTextureID); mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID()); const LevelInfoGL &levelInfo = mLevelInfo[level]; if (levelInfo.lumaWorkaround.enabled) { gl::Error error = mBlitter->copySubImageToLUMAWorkaroundTexture( mTextureID, mState.mTarget, target, levelInfo.sourceFormat, level, destOffset, sourceArea, source); if (error.isError()) { return error; } } else { if (UseTexImage2D(mState.mTarget)) { ASSERT(destOffset.z == 0); mFunctions->copyTexSubImage2D(target, static_cast<GLint>(level), destOffset.x, destOffset.y, sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height); } else if (UseTexImage3D(mState.mTarget)) { mFunctions->copyTexSubImage3D(target, static_cast<GLint>(level), destOffset.x, destOffset.y, destOffset.z, sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height); } else { UNREACHABLE(); } } return gl::Error(GL_NO_ERROR); }
gl::Error TextureGL::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const uint8_t *pixels) { ASSERT(CompatibleTextureTarget(mState.mTarget, target)); nativegl::TexSubImageFormat texSubImageFormat = nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type); mStateManager->bindTexture(mState.mTarget, mTextureID); if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpack.pixelBuffer.get() && unpack.rowLength != 0 && unpack.rowLength < area.width) { ANGLE_TRY(setSubImageRowByRowWorkaround(target, level, area, format, type, unpack, pixels)); } else if (UseTexImage2D(mState.mTarget)) { ASSERT(area.z == 0 && area.depth == 1); mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x, area.y, area.width, area.height, texSubImageFormat.format, texSubImageFormat.type, pixels); } else if (UseTexImage3D(mState.mTarget)) { mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, area.y, area.z, area.width, area.height, area.depth, texSubImageFormat.format, texSubImageFormat.type, pixels); } else { UNREACHABLE(); } ASSERT(mLevelInfo[level].lumaWorkaround.enabled == GetLevelInfo(format, texSubImageFormat.format).lumaWorkaround.enabled); return gl::Error(GL_NO_ERROR); }
gl::Error TextureGL::setSubImageRowByRowWorkaround(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const uint8_t *pixels) { gl::PixelUnpackState unpackToUse; unpackToUse.pixelBuffer = unpack.pixelBuffer; mStateManager->setPixelUnpackState(unpackToUse); unpackToUse.pixelBuffer.set(nullptr); GLenum sizedFormat = gl::GetSizedInternalFormat(mState.getImageDesc(mState.mTarget, level).internalFormat, type); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedFormat); GLuint rowBytes = 0; ANGLE_TRY_RESULT( formatInfo.computeRowPitch(GL_NONE, area.width, unpack.alignment, unpack.rowLength), rowBytes); GLuint imageBytes = 0; ANGLE_TRY_RESULT( formatInfo.computeDepthPitch(GL_NONE, area.width, area.height, unpack.alignment, unpack.rowLength, unpack.imageHeight), imageBytes); bool useTexImage3D = UseTexImage3D(mState.mTarget); GLuint skipBytes = 0; ANGLE_TRY_RESULT(formatInfo.computeSkipBytes(rowBytes, imageBytes, unpack.skipImages, unpack.skipRows, unpack.skipPixels, useTexImage3D), skipBytes); const uint8_t *pixelsWithSkip = pixels + skipBytes; if (useTexImage3D) { for (GLint image = 0; image < area.depth; ++image) { GLint imageByteOffset = image * imageBytes; for (GLint row = 0; row < area.height; ++row) { GLint byteOffset = imageByteOffset + row * rowBytes; const GLubyte *rowPixels = pixelsWithSkip + byteOffset; mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, row + area.y, image + area.z, area.width, 1, 1, format, type, rowPixels); } } } else if (UseTexImage2D(mState.mTarget)) { for (GLint row = 0; row < area.height; ++row) { GLint byteOffset = row * rowBytes; const GLubyte *rowPixels = pixelsWithSkip + byteOffset; mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x, row + area.y, area.width, 1, format, type, rowPixels); } } else { UNREACHABLE(); } return gl::NoError(); }