|
|
|
@@ -68,7 +68,7 @@ namespace MobileGL {
|
|
|
|
|
if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureLevelNumber(level)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureSizeRange(width, height)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureSizeRange(width, height, 1)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return;
|
|
|
|
|
|
|
|
|
|
// TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the
|
|
|
|
@@ -494,24 +494,16 @@ namespace MobileGL {
|
|
|
|
|
|
|
|
|
|
void TexImage3D_State(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
|
|
|
|
|
GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) {
|
|
|
|
|
// TODO: implement
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TexImage2D_State(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
|
|
|
|
|
GLint border, GLenum format, GLenum type, const void* pixels) {
|
|
|
|
|
MGLOG_D(
|
|
|
|
|
"TexImage2D_State called with target: %s, level: %d, internalformat: %s, width: %d, height: %d, "
|
|
|
|
|
"border: %d, format: %s, type: %s (%u), pixels: %p",
|
|
|
|
|
MG_Util::ConvertTextureUploadTargetToString(MG_Util::ConvertGLEnumToTextureUploadTarget(target))
|
|
|
|
|
.c_str(),
|
|
|
|
|
"%s called with target: %s, level: %d, internalformat: %s, width: %d, height: %d, depth: %d, "
|
|
|
|
|
"border: %d, format: %s, type: %s (%u), pixels: %p", __func__,
|
|
|
|
|
MG_Util::ConvertTextureUploadTargetToString(MG_Util::ConvertGLEnumToTextureUploadTarget(target)).c_str(),
|
|
|
|
|
level,
|
|
|
|
|
MG_Util::ConvertTextureInternalFormatToString(
|
|
|
|
|
MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat))
|
|
|
|
|
.c_str(),
|
|
|
|
|
width, height, border,
|
|
|
|
|
MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat)).c_str(),
|
|
|
|
|
width, height, depth, border,
|
|
|
|
|
MG_Util::ConvertTextureInputFormatToString(MG_Util::ConvertGLEnumToTextureInputFormat(format)).c_str(),
|
|
|
|
|
MG_Util::ConvertTexturePixelDataTypeToString(MG_Util::ConvertGLEnumToTexturePixelDataType(type))
|
|
|
|
|
.c_str(),
|
|
|
|
|
MG_Util::ConvertTexturePixelDataTypeToString(MG_Util::ConvertGLEnumToTexturePixelDataType(type)).c_str(),
|
|
|
|
|
type, pixels);
|
|
|
|
|
// ======================= Converting ================================
|
|
|
|
|
TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
|
|
|
|
@@ -526,7 +518,124 @@ namespace MobileGL {
|
|
|
|
|
if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureLevelNumber(level)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureSizeRange(width, height)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureSizeRange(width, height, depth)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureBorderNumber(border)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureInternalFormatCompatibleWithInput(
|
|
|
|
|
textureInputFormat, textureInternalFormat, texturePixelDataType))
|
|
|
|
|
return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return;
|
|
|
|
|
|
|
|
|
|
// TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the
|
|
|
|
|
// GL_PIXEL_UNPACK_BUFFER target and the buffer object's data store is currently mapped.
|
|
|
|
|
// GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER
|
|
|
|
|
// target and the data would be unpacked from the buffer object such that the memory reads required would
|
|
|
|
|
// exceed the data store size.
|
|
|
|
|
// GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER
|
|
|
|
|
// target and data is not evenly divisible into the number of bytes needed to store in memory a datum
|
|
|
|
|
// indicated by type.
|
|
|
|
|
// ======================= Processing ================================
|
|
|
|
|
SharedPtr<MG_State::GLState::ITextureObject> textureObject = nullptr;
|
|
|
|
|
Bool isProxy = TextureImpl::IsProxyTextureTarget(textureUploadingTarget);
|
|
|
|
|
if (isProxy) {
|
|
|
|
|
textureObject =
|
|
|
|
|
TextureImpl::pProxyTextureManager->CreateOrReplaceProxyTextureObject(textureUploadingTarget);
|
|
|
|
|
} else {
|
|
|
|
|
auto activeUnit =
|
|
|
|
|
MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
|
|
|
|
|
auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget);
|
|
|
|
|
textureObject = bindingSlot.GetBoundObject();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ===================== Error Checking ==============================
|
|
|
|
|
if (!TextureImpl::ValidateTextureObject(textureObject)) return;
|
|
|
|
|
|
|
|
|
|
// ======================= Processing ================================
|
|
|
|
|
|
|
|
|
|
SizeT imageSize = 0;
|
|
|
|
|
const SizeT inputBpp = MG_Util::GetInputBytesPerPixel(textureInputFormat, texturePixelDataType);
|
|
|
|
|
const SizeT internalBpp = MG_Util::GetInternalBytesPerPixel(textureInternalFormat, texturePixelDataType);
|
|
|
|
|
const SizeT internalBytes = width * height * depth * internalBpp;
|
|
|
|
|
|
|
|
|
|
textureObject->SetInternalFormat(textureInternalFormat);
|
|
|
|
|
|
|
|
|
|
// if isProxy, no more pixel transfer needed below
|
|
|
|
|
if (isProxy) return;
|
|
|
|
|
|
|
|
|
|
const void* originalPixels = pixels;
|
|
|
|
|
|
|
|
|
|
// PBO
|
|
|
|
|
const auto& pixelUnpackBufferObject =
|
|
|
|
|
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
|
|
|
|
if (pixelUnpackBufferObject) {
|
|
|
|
|
MGLOG_D("%s: Using Pixel Unpack Buffer Object ID: %u", __func__,
|
|
|
|
|
pixelUnpackBufferObject->GetExternalIndex());
|
|
|
|
|
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->GetDataReadOnly()->data()) +
|
|
|
|
|
reinterpret_cast<SizeT>(pixels);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get()),
|
|
|
|
|
"Texture object here should always be an object with mipmap");
|
|
|
|
|
auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
|
|
|
|
|
|
|
|
|
|
// Allocate in TextureObject
|
|
|
|
|
textureMipmapObject->AllocateStorage(textureUploadingTarget, level, {{width, height, depth}, internalBytes});
|
|
|
|
|
|
|
|
|
|
if (!originalPixels) {
|
|
|
|
|
MGLOG_D("%s: No input pixel and no PBO bound, no pixel transfer", __func__);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void* processedPixels = nullptr;
|
|
|
|
|
processedPixels = MG_Util::PixelStoreProcessor::ProcessTexturePixelsDataUnpack(
|
|
|
|
|
originalPixels, MG_State::pGLContext->GetPixelStoreParameters(true), textureInternalFormat,
|
|
|
|
|
textureInputFormat, texturePixelDataType, {width, height, depth}, false, imageSize);
|
|
|
|
|
|
|
|
|
|
if (processedPixels && imageSize > 0) {
|
|
|
|
|
if (imageSize != internalBytes) {
|
|
|
|
|
MGLOG_W("%s: Processed pixel data size (%zu) does not match expected size (%zu). "
|
|
|
|
|
"This may indicate an alignment or processing issue.", __func__,
|
|
|
|
|
imageSize, internalBytes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const SizeT copySize = std::min(imageSize, internalBytes);
|
|
|
|
|
DataPtr texelInput{processedPixels, copySize};
|
|
|
|
|
textureMipmapObject->UpdateMipmapSubData(textureUploadingTarget, level, texelInput);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
textureMipmapObject->MarkStorageDirty(textureUploadingTarget, level, true);
|
|
|
|
|
|
|
|
|
|
free(processedPixels);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TexImage2D_State(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
|
|
|
|
|
GLint border, GLenum format, GLenum type, const void* pixels) {
|
|
|
|
|
MGLOG_D(
|
|
|
|
|
"%s called with target: %s, level: %d, internalformat: %s, width: %d, height: %d, "
|
|
|
|
|
"border: %d, format: %s, type: %s (%u), pixels: %p", __func__,
|
|
|
|
|
MG_Util::ConvertTextureUploadTargetToString(MG_Util::ConvertGLEnumToTextureUploadTarget(target)).c_str(),
|
|
|
|
|
level,
|
|
|
|
|
MG_Util::ConvertTextureInternalFormatToString(
|
|
|
|
|
MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat)).c_str(),
|
|
|
|
|
width, height, border,
|
|
|
|
|
MG_Util::ConvertTextureInputFormatToString(MG_Util::ConvertGLEnumToTextureInputFormat(format)).c_str(),
|
|
|
|
|
MG_Util::ConvertTexturePixelDataTypeToString(MG_Util::ConvertGLEnumToTexturePixelDataType(type)).c_str(),
|
|
|
|
|
type, pixels);
|
|
|
|
|
// ======================= Converting ================================
|
|
|
|
|
TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
|
|
|
|
|
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
|
|
|
|
|
TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format);
|
|
|
|
|
TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type);
|
|
|
|
|
TextureInternalFormat textureInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat);
|
|
|
|
|
|
|
|
|
|
// ===================== Error Checking ==============================
|
|
|
|
|
if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureLevelNumber(level)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureSizeRange(width, height, 1)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureBorderNumber(border)) return;
|
|
|
|
|
if (!TextureImpl::ValidateTextureInternalFormatCompatibleWithInput(
|
|
|
|
@@ -577,7 +686,7 @@ namespace MobileGL {
|
|
|
|
|
const auto& pixelUnpackBufferObject =
|
|
|
|
|
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
|
|
|
|
if (pixelUnpackBufferObject) {
|
|
|
|
|
MGLOG_D("TexImage2D_State: Using Pixel Unpack Buffer Object ID: %u",
|
|
|
|
|
MGLOG_D("%s: Using Pixel Unpack Buffer Object ID: %u", __func__,
|
|
|
|
|
pixelUnpackBufferObject->GetExternalIndex());
|
|
|
|
|
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->GetDataReadOnly()->data()) +
|
|
|
|
|
reinterpret_cast<SizeT>(pixels);
|
|
|
|
@@ -591,7 +700,7 @@ namespace MobileGL {
|
|
|
|
|
textureMipmapObject->AllocateStorage(textureUploadingTarget, level, {{width, height, 1}, internalBytes});
|
|
|
|
|
|
|
|
|
|
if (!originalPixels) {
|
|
|
|
|
MGLOG_D("TexImage2D_State: No input pixel and no PBO bound, no pixel transfer");
|
|
|
|
|
MGLOG_D("%s: No input pixel and no PBO bound, no pixel transfer", __func__);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -1153,6 +1262,7 @@ namespace MobileGL {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BindTexture_State(GLenum target, GLuint texture) {
|
|
|
|
|
// TODO: deal with condition where texture == 0
|
|
|
|
|
MGLOG_D("BindTexture_State called with target: 0x%X, texture: %u", target, texture);
|
|
|
|
|
// ======================= Converting ================================
|
|
|
|
|
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
|
|
|
|
|